diff --git a/libraries/forms.py b/libraries/forms.py
index cd50fea0..543c648b 100644
--- a/libraries/forms.py
+++ b/libraries/forms.py
@@ -779,7 +779,9 @@ def get_stats(self):
).aggregate(lines=Sum("deletions"))["lines"]
# we want 2 channels per pdf page, use batched to get groups of 2
slack_stats = batched(self._get_slack_stats(prior_version, version), 2)
+ committee_members = version.financial_committee_members.all()
return {
+ "committee_members": committee_members,
"lines_added": lines_added,
"lines_removed": lines_removed,
"wordcloud_base64": self._generate_hyperkitty_word_cloud(version),
diff --git a/templates/admin/release_report_detail.html b/templates/admin/release_report_detail.html
index 029c5b3f..dd502281 100644
--- a/templates/admin/release_report_detail.html
+++ b/templates/admin/release_report_detail.html
@@ -139,8 +139,20 @@
{% include "admin/_release_report_top_left_logo.html" %}
From the Fiscal Sponsorship Committee
-
{% endif %}
diff --git a/users/admin.py b/users/admin.py
index e5e4596a..a07a063c 100644
--- a/users/admin.py
+++ b/users/admin.py
@@ -43,6 +43,10 @@ class EmailUserAdmin(UserAdmin):
)
},
),
+ (
+ _("High Quality Image"),
+ {"fields": ("hq_image",)},
+ ),
)
add_fieldsets = (
(None, {"classes": ("wide",), "fields": ("email", "password1", "password2")}),
diff --git a/users/migrations/0016_user_hq_image.py b/users/migrations/0016_user_hq_image.py
new file mode 100644
index 00000000..ff92140b
--- /dev/null
+++ b/users/migrations/0016_user_hq_image.py
@@ -0,0 +1,31 @@
+# Generated by Django 4.2.16 on 2025-01-22 22:39
+
+import core.validators
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("users", "0015_user_delete_permanently_at"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="user",
+ name="hq_image",
+ field=models.FileField(
+ blank=True,
+ help_text="A high-quality image of the user - used in profiles/reports.",
+ null=True,
+ upload_to="hiqh-quality-user-images",
+ validators=[
+ core.validators.FileTypeValidator(
+ extensions=[".jpg", ".jpeg", ".png"]
+ ),
+ core.validators.MaxFileSizeValidator(max_size=52428800),
+ ],
+ verbose_name="High Quality Image",
+ ),
+ ),
+ ]
diff --git a/users/models.py b/users/models.py
index 4c51d410..fb2661df 100644
--- a/users/models.py
+++ b/users/models.py
@@ -20,7 +20,11 @@
from imagekit.models import ImageSpecField
from imagekit.processors import ResizeToFill
-from core.validators import image_validator, max_file_size_validator
+from core.validators import (
+ image_validator,
+ max_file_size_validator,
+ large_file_max_size_validator,
+)
logger = logging.getLogger(__name__)
@@ -221,6 +225,20 @@ class User(BaseUser):
format="JPEG",
options={"quality": 90},
)
+ hq_image = models.FileField(
+ upload_to="hiqh-quality-user-images",
+ help_text="A high-quality image of the user - used in profiles/reports.",
+ null=True,
+ blank=True,
+ validators=[image_validator, large_file_max_size_validator],
+ verbose_name="High Quality Image",
+ )
+ hq_image_render = ImageSpecField(
+ source="hq_image",
+ processors=[ResizeToFill(4096, 4096)],
+ format="JPEG",
+ options={"quality": 90},
+ )
claimed = models.BooleanField(
_("claimed"),
default=True,
@@ -318,6 +336,9 @@ def delete_account(self):
self.delete_permanently_at = None
self.save()
+ def __str__(self):
+ return f"{self.first_name} {self.last_name} <{self.email}>"
+
class LastSeen(models.Model):
"""
diff --git a/versions/admin.py b/versions/admin.py
index 2b52b92b..9b24ef05 100755
--- a/versions/admin.py
+++ b/versions/admin.py
@@ -30,6 +30,7 @@ class VersionAdmin(admin.ModelAdmin):
search_fields = ["name", "description"]
date_hierarchy = "release_date"
inlines = [VersionFileInline]
+ filter_horizontal = ["financial_committee_members"]
change_list_template = "admin/version_change_list.html"
def get_urls(self):
diff --git a/versions/migrations/0018_version_financial_committee_members.py b/versions/migrations/0018_version_financial_committee_members.py
new file mode 100644
index 00000000..544ae8b8
--- /dev/null
+++ b/versions/migrations/0018_version_financial_committee_members.py
@@ -0,0 +1,24 @@
+# Generated by Django 4.2.16 on 2025-01-21 01:15
+
+from django.conf import settings
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ migrations.swappable_dependency(settings.AUTH_USER_MODEL),
+ ("versions", "0017_alter_review_review_manager_alter_review_submitters"),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name="version",
+ name="financial_committee_members",
+ field=models.ManyToManyField(
+ blank=True,
+ help_text="Financial Committee members who are responsible for this release.",
+ to=settings.AUTH_USER_MODEL,
+ ),
+ ),
+ ]
diff --git a/versions/models.py b/versions/models.py
index 4e735ebe..393f1eba 100755
--- a/versions/models.py
+++ b/versions/models.py
@@ -47,7 +47,11 @@ class Version(models.Model):
blank=True,
help_text='Message to show in release reports on the "Fiscal Sponsorship Committee" page.', # noqa: E501
)
-
+ financial_committee_members = models.ManyToManyField(
+ User,
+ blank=True,
+ help_text="Financial Committee members who are responsible for this release.",
+ )
objects = VersionManager()
def __str__(self):