Added library graphic; sorting by library "great","good","standard" (#1624)

This commit is contained in:
daveoconnor
2025-02-11 02:18:50 +00:00
committed by GitHub
parent d537985bb8
commit ead361e811
5 changed files with 121 additions and 41 deletions

View File

@@ -0,0 +1,11 @@
from django.db import models
from django.db.models.fields.files import FieldFile
class NullableFileField(models.FileField):
def get_db_prep_value(self, value, connection, prepared=False):
if isinstance(value, FieldFile):
if not value.name:
return None
value = value.name
return super().get_db_prep_value(value, connection, prepared)

View File

@@ -1,7 +1,7 @@
import io
import base64
from functools import cached_property
from itertools import groupby
from itertools import groupby, chain
from operator import attrgetter
from dataclasses import dataclass, field
from datetime import date, timedelta
@@ -271,14 +271,18 @@ class CreateReportForm(CreateReportFullForm):
)
def _get_top_libraries_for_version(self):
return (
self.library_queryset.filter(
library_version=LibraryVersion.objects.filter(
library=OuterRef("id"), version=self.cleaned_data["version"]
)[:1],
base_queryset = self.library_queryset.filter(
library_version=LibraryVersion.objects.filter(
library=OuterRef("id"), version=self.cleaned_data["version"]
)[:1],
).order_by("name")
# returns "great", "good", and "standard" libraries in that order
return list(
chain(
base_queryset.filter(graphic__isnull=False),
base_queryset.filter(graphic__isnull=True, is_good=True),
base_queryset.filter(graphic__isnull=True, is_good=False),
)
.annotate(commit_count=Count("library_version__commit"))
.order_by("-commit_count")
)
def _get_library_version_counts(self, libraries, library_order):
@@ -703,15 +707,11 @@ class CreateReportForm(CreateReportFullForm):
top_libraries_for_version = self._get_top_libraries_for_version()
library_order = self._get_library_order(top_libraries_for_version)
libraries = Library.objects.filter(id__in=library_order)
library_names = (
LibraryVersion.objects.filter(
version=version,
library__in=self.library_queryset,
)
.annotate(name=F("library__name"))
.order_by("name")
.values_list("name", flat=True)
)
all_libraries = Library.objects.filter(
library_version__version=version,
library_version__library__in=self.library_queryset,
).order_by("name")
library_data = [
{
"library": item[0],
@@ -810,7 +810,7 @@ class CreateReportForm(CreateReportFullForm):
"top_libraries_for_version": top_libraries_for_version,
"library_count": library_count,
"library_count_prior": library_count_prior,
"library_names": library_names,
"all_libraries": all_libraries,
"added_library_count": added_library_count,
"removed_library_count": removed_library_count,
"downloads": downloads,

View File

@@ -0,0 +1,41 @@
# Generated by Django 4.2.16 on 2025-02-05 21:58
import core.custom_model_fields
import core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
("libraries", "0027_libraryversion_dependencies"),
]
operations = [
migrations.AddField(
model_name="library",
name="graphic",
field=core.custom_model_fields.NullableFileField(
blank=True,
default=None,
null=True,
upload_to="library_graphics",
validators=[
core.validators.FileTypeValidator(
extensions=[".jpg", ".jpeg", ".png"]
),
core.validators.MaxFileSizeValidator(max_size=1048576),
],
verbose_name="Library Graphic",
),
),
migrations.AddField(
model_name="library",
name="is_good",
field=models.BooleanField(
default=False,
help_text="Is this library considered 'good' by the Boost community?",
verbose_name="Good Library",
),
),
]

View File

@@ -8,10 +8,11 @@ from django.db.models import Sum
from django.utils.functional import cached_property
from django.utils.text import slugify
from django.db.models.functions import Upper
from core.custom_model_fields import NullableFileField
from core.markdown import process_md
from core.models import RenderedContent
from core.asciidoc import convert_adoc_to_html
from core.validators import image_validator, max_file_size_validator
from libraries.managers import IssueManager
from mailing_list.models import EmailData
from .constants import LIBRARY_GITHUB_URL_OVERRIDES
@@ -151,6 +152,19 @@ class Library(models.Model):
description = models.TextField(
blank=True, null=True, help_text="The description of the library."
) # holds the most recent version's description
graphic = NullableFileField(
upload_to="library_graphics",
blank=True,
null=True,
default=None,
validators=[image_validator, max_file_size_validator],
verbose_name="Library Graphic",
)
is_good = models.BooleanField(
default=False,
verbose_name="Good Library",
help_text="Is this library considered 'good' by the Boost community?",
)
github_url = models.URLField(
max_length=500,
blank=True,
@@ -216,6 +230,15 @@ class Library(models.Model):
return "".join(processed_segments)
@cached_property
def group(self):
if self.graphic:
return "great"
elif self.is_good:
return "good"
else:
return "standard"
def __str__(self):
return self.name

View File

@@ -315,9 +315,14 @@ body {
<div class="flex flex-col h-full mx-auto w-full">
<h2 class="mx-auto">Library Index</h2>
<div class="flex flex-col flex-wrap gap-x-4 gap-y-1 text-xs h-5/6">
{% for name in library_names %}
{% for library in all_libraries %}
<div class="max-w-[10rem]">
{{ name }}
{{ library.name }}
{% if library.group == "great" %}
<i class="text-orange fa-solid fa-star"></i>
{% elif library.group == "good" %}
<i class="text-orange fa-regular fa-star"></i>
{% endif %}
</div>
{% endfor %}
</div>
@@ -325,29 +330,13 @@ body {
{% include "admin/_release_report_page_footer.html" %}
</div>
{% for item in library_data %}
<div class="pdf-page flex flex-col items-center justify-center {{ bg_color }}">
<div class="pdf-page flex flex-col {{ bg_color }}">
<div class="grid grid-cols-3 gap-x-8 w-full p-4">
<div class="px-4">
<div class="mx-auto mb-6">Top Contributors</div>
<div class="m-auto grid grid-cols-1 gap-2">
{% for author in item.top_contributors_release %}
<div class="flex flex-row gap-y-2 w-40 items-center">
{% avatar commitauthor=author %}
<div class="w-full flex flex-col ml-2">
<div class="text-[0.8rem] font-semibold overflow-ellipsis overflow-hidden whitespace-nowrap w-full">
{{ author.name }}
</div>
<div class="text-[0.7rem]"><span class="font-bold">{{ author.commit_count }}</span> commit{{ author.commit_count|pluralize }}</div>
</div>
</div>
{% endfor %}
</div>
</div>
<div class="col-span-2 flex flex-col gap-y-4">
<div>
<h2 class="text-orange mb-1 mt-0">{{ item.library.name }}</h2>
<div class="flex flex-col gap-y-4">
<h2 class="text-orange mb-1 mt-0">{{ item.library.display_name }}</h2>
<div>{{ item.library.description }}</div>
{% if item.library.graphic %}<div><img src="{{ item.library.graphic.url }}" alt="" /></div>{% endif %}
</div>
<div class="flex flex-col gap-y-1">
<div>
@@ -382,6 +371,22 @@ body {
{% endif %}
</div>
</div>
<div class="px-4">
<div class="mx-auto mb-6">Top Contributors</div>
<div class="m-auto grid grid-cols-1 gap-2">
{% for author in item.top_contributors_release %}
<div class="flex flex-row gap-y-2 w-40 items-center">
{% avatar commitauthor=author %}
<div class="w-full flex flex-col ml-2">
<div class="text-[0.8rem] font-semibold overflow-ellipsis overflow-hidden whitespace-nowrap w-full">
{{ author.name }}
</div>
<div class="text-[0.7rem]"><span class="font-bold">{{ author.commit_count }}</span> commit{{ author.commit_count|pluralize }}</div>
</div>
</div>
{% endfor %}
</div>
</div>
</div>
{% include "admin/_release_report_page_footer.html" %}
</div>