[RFC PATCH 1/4] patch-detail: add patch relation context

Raxel Gutierrez raxel at google.com
Tue Aug 24 01:49:40 AEST 2021


Hi,

Forgot to make the changes so that the templatetags/patch.py changes
don't exist. Can use the utils.py generic is_editable instead.

Best,
Raxel

On Mon, Aug 23, 2021 at 10:58 AM Raxel Gutierrez <raxel at google.com> wrote:
>
> These changes are setup for the upcoming change that adds a patch
> relations table to the submission page. In particular:
>
> - Add unaddressed and addressed counts to patches and patch relations to
>   be able to view the information in the patch relations table.
> - Change the current patch tags count filter to a function of the patch
>   object so that it can be used by the patch relations tags count filter.
> - Add template filter that retrieves a summary of the existence of tags
>   (e.g. A/R/T) for a given patch relation.
> - Add the project maintainers as context to be auto-generate them in an
>   email in the case that patch relations need to be modified.
>
> Signed-off-by: Raxel Gutierrez <raxel at google.com>
> ---
>  patchwork/models.py                           | 36 +++++++++++++++++++
>  patchwork/templates/patchwork/submission.html |  4 +++
>  patchwork/templatetags/patch.py               | 34 ++++++++++++------
>  patchwork/views/patch.py                      | 23 +++++++++---
>  4 files changed, 83 insertions(+), 14 deletions(-)
>
> diff --git a/patchwork/models.py b/patchwork/models.py
> index 58e4c51e..b1d8c5bc 100644
> --- a/patchwork/models.py
> +++ b/patchwork/models.py
> @@ -462,6 +462,14 @@ class Patch(SubmissionMixin):
>
>      objects = PatchManager()
>
> +    @property
> +    def unaddressed_comments_count(self):
> +        return self.comments.filter(addressed=False).count()
> +
> +    @property
> +    def addressed_comments_count(self):
> +        return self.comments.filter(addressed=True).count()
> +
>      @staticmethod
>      def extract_tags(content, tags):
>          counts = Counter()
> @@ -494,6 +502,18 @@ class Patch(SubmissionMixin):
>          for tag in tags:
>              self._set_tag(tag, counter[tag])
>
> +    def patch_tags_count(self):
> +        counts = []
> +        titles = []
> +        for tag in [t for t in self.project.tags if t.show_column]:
> +            count = getattr(self, tag.attr_name)
> +            titles.append('%d %s' % (count, tag.name))
> +            if count == 0:
> +                counts.append("-")
> +            else:
> +                counts.append(count)
> +        return counts, titles
> +
>      def save(self, *args, **kwargs):
>          if not hasattr(self, 'state') or not self.state:
>              self.state = get_default_initial_patch_state()
> @@ -950,6 +970,22 @@ class BundlePatch(models.Model):
>
>  class PatchRelation(models.Model):
>
> +    @property
> +    def unaddressed_comments_total(self):
> +        total = 0
> +        patches = self.patches.all()
> +        for patch in patches:
> +            total += patch.unaddressed_comments_count
> +        return total
> +
> +    @property
> +    def addressed_comments_total(self):
> +        total = 0
> +        patches = self.patches.all()
> +        for patch in patches:
> +            total += patch.addressed_comments_count
> +        return total
> +
>      def __str__(self):
>          patches = self.patches.all()
>          if not patches:
> diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html
> index 2238e82e..7dd6ae97 100644
> --- a/patchwork/templates/patchwork/submission.html
> +++ b/patchwork/templates/patchwork/submission.html
> @@ -9,6 +9,10 @@
>
>  {% block headers %}
>    <script type="module" src="{% static "js/submission.js" %}"></script>
> +  <script type="text/javascript">
> +    let is_editable = {{ editable|yesno:"true,false" }};
> +    let django_maintainers_data = {{ maintainers|safe }}
> +  </script>
>  {% endblock %}
>
>  {% block title %}{{submission.name}}{% endblock %}
> diff --git a/patchwork/templatetags/patch.py b/patchwork/templatetags/patch.py
> index 3837798d..c07c0bee 100644
> --- a/patchwork/templatetags/patch.py
> +++ b/patchwork/templatetags/patch.py
> @@ -16,18 +16,25 @@ register = template.Library()
>
>  @register.filter(name='patch_tags')
>  def patch_tags(patch):
> -    counts = []
> -    titles = []
> -    for tag in [t for t in patch.project.tags if t.show_column]:
> -        count = getattr(patch, tag.attr_name)
> -        titles.append('%d %s' % (count, tag.name))
> -        if count == 0:
> -            counts.append("-")
> -        else:
> -            counts.append(str(count))
> +    counts, titles = patch.patch_tags_count()
>      return mark_safe('<span title="%s">%s</span>' % (
>          ' / '.join(titles),
> -        ' '.join(counts)))
> +        ' '.join([str(x) for x in counts])))
> +
> +
> + at register.filter(name='patch_relation_tags')
> +def patch_relation_tags(related_patches, project):
> +    tags = [tag.abbrev for tag in project.tags]
> +    tags_summary = ["-" for _ in range(len(tags))]
> +    for patch in related_patches:
> +        counts = patch.patch_tags_count()[0]
> +        for i, count in enumerate(counts):
> +            if count != '-':
> +                # Replaces a non-zero tag count with tag abbreviation
> +                # to indicate that existence of such tag in the set
> +                # of related patches
> +                tags_summary[i] = tags[i]
> +    return mark_safe('<span>%s</span>' % (' '.join(tags_summary)))
>
>
>  @register.filter(name='patch_checks')
> @@ -71,3 +78,10 @@ def patch_commit_display(patch):
>
>      return mark_safe('<a href="%s">%s</a>' % (escape(fmt.format(commit)),
>                                                escape(commit)))
> +
> +
> +# TODO: can be modularized into a utils.py templatetags file
> +# to get is_editable from any object
> + at register.filter(name='patch_is_editable')
> +def patch_is_editable(patch, user):
> +    return patch.is_editable(user)
> diff --git a/patchwork/views/patch.py b/patchwork/views/patch.py
> index 00b0147f..8e685add 100644
> --- a/patchwork/views/patch.py
> +++ b/patchwork/views/patch.py
> @@ -40,7 +40,11 @@ def patch_detail(request, project_id, msgid):
>
>      # redirect to cover letters where necessary
>      try:
> -        patch = Patch.objects.get(project_id=project.id, msgid=db_msgid)
> +        # Current patch needs tag counts when no relation exists
> +        patch_qs = Patch.objects.filter(
> +            project_id=project.id, msgid=db_msgid
> +        ).with_tag_counts(project)
> +        patch = patch_qs.get()
>      except Patch.DoesNotExist:
>          covers = Cover.objects.filter(
>              project_id=project.id,
> @@ -113,15 +117,19 @@ def patch_detail(request, project_id, msgid):
>                               'addressed')
>
>      if patch.related:
> -        related_same_project = patch.related.patches.only(
> -            'name', 'msgid', 'project', 'related')
> +        related_same_project = patch.related.patches.order_by('-id').only(
> +            'name', 'msgid', 'project', 'related').with_tag_counts(project)
> +        related_ids = {'ids': [rp.id for rp in related_same_project]}
>          # avoid a second trip out to the db for info we already have
>          related_different_project = [
>              related_patch for related_patch in related_same_project
>              if related_patch.project_id != patch.project_id
>          ]
>      else:
> -        related_same_project = []
> +        # If no patch relation exists, then current patch is only related.
> +        # Add tag counts to the patch to display in patch relation table.
> +        related_same_project = [patch]
> +        related_ids = {'ids': [patch.id]}
>          related_different_project = []
>
>      context['comments'] = comments
> @@ -133,7 +141,14 @@ def patch_detail(request, project_id, msgid):
>      context['patchform'] = form
>      context['createbundleform'] = createbundleform
>      context['project'] = patch.project
> +    context['maintainers'] = {
> +        'maintainers': [
> +            m.user.email for m in patch.project.maintainer_project.all()
> +        ]
> +    }
> +    context['patch_relation'] = patch.related
>      context['related_same_project'] = related_same_project
> +    context['related_ids'] = related_ids
>      context['related_different_project'] = related_different_project
>
>      return render(request, 'patchwork/submission.html', context)
> --
> 2.33.0.rc2.250.ged5fa647cd-goog
>


More information about the Patchwork mailing list