Skip to content

Commit

Permalink
Add permission to edit all problem types & group
Browse files Browse the repository at this point in the history
  • Loading branch information
leduythuccs committed Feb 13, 2025
1 parent d8c0c04 commit c29c778
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 1 deletion.
1 change: 1 addition & 0 deletions dmoj/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ def paged_list_view(view, name):
path('problem/<str:problem>', include([
path('', problem.ProblemDetail.as_view(), name='problem_detail'),
path('/edit', problem.ProblemEdit.as_view(), name='problem_edit'),
path('/edit-type-group', problem.ProblemEditTypeGroup.as_view(), name='problem_edit_type_group'),
path('/editorial', problem.ProblemSolution.as_view(), name='problem_editorial'),
path('/raw', xframe_options_sameorigin(problem.ProblemRaw.as_view()), name='problem_raw'),
path('/pdf', problem.ProblemPdfView.as_view(), name='problem_pdf'),
Expand Down
10 changes: 10 additions & 0 deletions judge/forms.py
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,16 @@ class Meta:
}


class ProblemEditTypeGroupForm(ModelForm):
class Meta:
model = Problem
fields = ['types', 'group']
widgets = {
'types': Select2MultipleWidget,
'group': Select2Widget,
}


class ProblemImportPolygonForm(Form):
code = CharField(max_length=32, validators=[RegexValidator('^[a-z0-9_]+$', _('Problem code must be ^[a-z0-9_]+$'))])
package = forms.FileField(
Expand Down
17 changes: 17 additions & 0 deletions judge/migrations/0211_edit_type_group_all_problem.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Generated by Django 3.2.19 on 2025-02-13 12:04

from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('judge', '0210_clarify_rate_all_desc'),
]

operations = [
migrations.AlterModelOptions(
name='problem',
options={'permissions': (('see_private_problem', 'See hidden problems'), ('edit_own_problem', 'Edit own problems'), ('create_organization_problem', 'Create organization problem'), ('edit_all_problem', 'Edit all problems'), ('edit_public_problem', 'Edit all public problems'), ('suggest_new_problem', 'Suggest new problem'), ('problem_full_markup', 'Edit problems with full markup'), ('clone_problem', 'Clone problem'), ('upload_file_statement', 'Upload file-type statement'), ('change_public_visibility', 'Change is_public field'), ('change_manually_managed', 'Change is_manually_managed field'), ('see_organization_problem', 'See organization-private problems'), ('import_polygon_package', 'Import Codeforces Polygon package'), ('edit_type_group_all_problem', 'Edit type and group for all problems')), 'verbose_name': 'problem', 'verbose_name_plural': 'problems'},
),
]
1 change: 1 addition & 0 deletions judge/models/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -624,6 +624,7 @@ class Meta:
('change_manually_managed', _('Change is_manually_managed field')),
('see_organization_problem', _('See organization-private problems')),
('import_polygon_package', _('Import Codeforces Polygon package')),
('edit_type_group_all_problem', _('Edit type and group for all problems')),
)
verbose_name = _('problem')
verbose_name_plural = _('problems')
Expand Down
27 changes: 26 additions & 1 deletion judge/views/problem.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from judge.comments import CommentedDetailView
from judge.forms import LanguageLimitFormSet, ProblemCloneForm, ProblemEditForm, ProblemImportPolygonForm, \
ProblemImportPolygonStatementFormSet, ProblemSubmitForm, ProposeProblemSolutionFormSet
ProblemImportPolygonStatementFormSet, ProblemSubmitForm, ProblemEditTypeGroupForm, ProposeProblemSolutionFormSet
from judge.models import ContestSubmission, Judge, Language, Problem, ProblemGroup, \
ProblemTranslation, ProblemType, RuntimeVersion, Solution, Submission, SubmissionSource
from judge.tasks import on_new_problem
Expand Down Expand Up @@ -1046,3 +1046,28 @@ def dispatch(self, request, *args, **kwargs):
except PermissionDenied:
return generic_message(request, _("Can't edit problem"),
_('You are not allowed to edit this problem.'), status=403)


class ProblemEditTypeGroup(ProblemMixin, TitleMixin, UpdateView, PermissionRequiredMixin):
template_name = 'problem/type-group-editor.html'
model = Problem
form_class = ProblemEditTypeGroupForm
permission_required = 'judge.edit_all_problem'

def get_title(self):
return _('Editing problem {0}').format(self.object.name)

def post(self, request, *args, **kwargs):
self.object = self.get_object()
form = self.get_form()
if form.is_valid():
with revisions.create_revision(atomic=True):
problem = form.save()
problem.save()

revisions.set_comment(_('Edited types/group from site'))
revisions.set_user(self.request.user)

return HttpResponseRedirect(reverse('problem_detail', args=[self.object.code]))

return self.render_to_response(self.get_context_data(object=self.object))
4 changes: 4 additions & 0 deletions templates/problem/problem.html
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,10 @@ <h2 style="display: inline-block">{{ title }}</h2>
</div>
{% endif %}

{% if perms.judge.edit_all_problem %}
<div><a href="{{ url('problem_edit_type_group', problem.code) }}">{{ _('Edit type group') }}</a></div>
{% endif %}

{% if problem.is_subs_manageable_by(request.user) %}
<div>
<a href="{{ url('problem_manage_submissions', problem.code) }}">{{ _('Manage submissions') }}</a>
Expand Down
25 changes: 25 additions & 0 deletions templates/problem/type-group-editor.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{% extends "base.html" %}

{% block js_media %}
{{ form.media.js }}
{% include "leave-warning.html" %}

<script src="{{ static('vnoj/jquery.formset.js') }}"></script>
{% endblock %}

{% block body %}
<div>
<form action="" method="post" class="form-area" enctype="multipart/form-data" style="display: flex; justify-content: center; flex-direction: column;">
{% if form.errors %}
<p class="errornote"> {{ _('Please correct the error below.') }}</p>
{% endif %}
{% csrf_token %}
<table class="django-as-table">{{ form.as_table() }}</table>
<hr>
<table>
<tr><td style="float: left;">
<td style="float: right;"><input type="submit" value="{{ _('Update') }}" class="button"></td></tr>
</table>
</form>
</div>
{% endblock %}

0 comments on commit c29c778

Please sign in to comment.