diff --git a/judge/admin/problem.py b/judge/admin/problem.py index c78c0981f6..ce5baee2b5 100644 --- a/judge/admin/problem.py +++ b/judge/admin/problem.py @@ -125,9 +125,10 @@ class ProblemAdmin(NoBatchDeleteMixin, VersionAdmin): 'fields': ( 'code', 'name', 'is_public', 'is_manually_managed', 'date', 'authors', 'curators', 'testers', 'organizations', 'submission_source_visibility_mode', 'is_full_markup', - 'description', 'license', + 'description', ), }), + (_('Authorship'), {'fields': (('authorship_name', 'authorship_uri'), 'license')}), (_('Social Media'), {'classes': ('collapse',), 'fields': ('og_image', 'summary')}), (_('Taxonomy'), {'fields': ('types', 'group')}), (_('Points'), {'fields': (('points', 'partial'), 'short_circuit')}), diff --git a/judge/admin/submission.py b/judge/admin/submission.py index ba2fcf229e..ce8bf9ed9f 100644 --- a/judge/admin/submission.py +++ b/judge/admin/submission.py @@ -75,7 +75,7 @@ def get_formset(self, request, obj=None, **kwargs): def formfield_for_dbfield(self, db_field, **kwargs): submission = kwargs.pop('obj', None) - label = None + # label = None if submission: if db_field.name == 'participation': kwargs['queryset'] = ContestParticipation.objects.filter(user=submission.user, diff --git a/judge/migrations/0147_problem_authorship.py b/judge/migrations/0147_problem_authorship.py new file mode 100644 index 0000000000..c2a1d36648 --- /dev/null +++ b/judge/migrations/0147_problem_authorship.py @@ -0,0 +1,23 @@ +# Generated by Django 3.2.23 on 2024-01-02 08:20 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('judge', '0146_comment_revision_count_v2'), + ] + + operations = [ + migrations.AddField( + model_name='problem', + name='authorship_name', + field=models.CharField(blank=True, help_text="Use it for attribution purposes, the original author's name will be added at the end of the problem.", max_length=100, verbose_name="author's name"), + ), + migrations.AddField( + model_name='problem', + name='authorship_uri', + field=models.URLField(blank=True, max_length=255, verbose_name="author's URI"), + ), + ] diff --git a/judge/models/problem.py b/judge/models/problem.py index aa436724fb..c4f203a357 100644 --- a/judge/models/problem.py +++ b/judge/models/problem.py @@ -124,6 +124,10 @@ class Problem(models.Model): authors = models.ManyToManyField(Profile, verbose_name=_('creators'), blank=True, related_name='authored_problems', help_text=_('These users will be able to edit the problem, ' 'and be listed as authors.')) + authorship_name = models.CharField(max_length=100, verbose_name=_("author's name"), blank=True, + help_text=_("Use it for attribution purposes, the original author's name will " + 'be added at the end of the problem.')) + authorship_uri = models.URLField(max_length=255, verbose_name=_("author's URI"), blank=True) curators = models.ManyToManyField(Profile, verbose_name=_('curators'), blank=True, related_name='curated_problems', help_text=_('These users will be able to edit the problem, ' 'but not be listed as authors.')) diff --git a/templates/problem/problem.html b/templates/problem/problem.html index 7135717652..85b675d443 100644 --- a/templates/problem/problem.html +++ b/templates/problem/problem.html @@ -41,6 +41,19 @@ .problem-info-entry { padding-top: 0.5em; } + + .authorship { + font-style: italic; + font-weight: bold; + } + + .authorship a { + font-weight: normal; + } + + .authorship hr { + margin-bottom: 10px; + } {% endblock %} @@ -304,6 +317,22 @@

{{ title }}

{{ description|markdown(problem.markdown_style, MATH_ENGINE)|reference|str|safe }} {% endcache %} + {% if problem.authorship_name %} + +
+ {% trans trimmed %} Authorship: {% endtrans %} + + {% if problem.authorship_uri %} + + {{ problem.authorship_name }} + + {% else %} + {{ problem.authorship_name }} + {% endif %} +
+
+ {% endif %} + {% with license=problem.license %} {% if license %}