From c6cbea5f1557e3adcade812e9125d1a56163f86a Mon Sep 17 00:00:00 2001
From: FherStk <porrino.fernando@gmail.com>
Date: Tue, 26 Dec 2023 15:12:50 +0000
Subject: [PATCH] Attribution data can now be added to a problem (author +
 link) and it will be displayed at the end of the problem's statement.

---
 judge/admin/problem.py                      |  3 ++-
 judge/admin/submission.py                   |  2 +-
 judge/migrations/0147_problem_authorship.py | 23 ++++++++++++++++
 judge/models/problem.py                     |  4 +++
 templates/problem/problem.html              | 29 +++++++++++++++++++++
 5 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 judge/migrations/0147_problem_authorship.py

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;       
+        }
     </style>
 {% endblock %}
 
@@ -304,6 +317,22 @@ <h2 style="display: inline-block">{{ title }}</h2>
         {{ description|markdown(problem.markdown_style, MATH_ENGINE)|reference|str|safe }}
     {% endcache %}
 
+    {% if problem.authorship_name %}
+        <span class="authorship">
+            <hr>
+            {% trans trimmed %} Authorship: {% endtrans %}          
+            
+            {% if problem.authorship_uri %}
+                <a href="{{ problem.authorship_uri }}">
+                    {{ problem.authorship_name }}
+                </a>
+            {% else %}
+                {{ problem.authorship_name }}
+            {% endif %}
+        </span>
+        <br />
+    {% endif %}
+
     {% with license=problem.license %}
         {% if license %}
             <span class="license">