Message ID | 20210823145847.3944896-2-raxel@google.com |
---|---|
State | RFC |
Headers | show |
Series | patch-detail: add patch relations table | expand |
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@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@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]))) > + > + > +@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 > +@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 >
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]))) + + +@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 +@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)
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@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(-)