[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