Re: [PATCH v2 2/2] docs: Note new requirement to include a SPDX line
On Mon, 2018-09-17 at 13:34 -0400, Veronika Kabatova wrote: > > - Original Message - > > From: "Stephen Finucane" > > To: patchwork@lists.ozlabs.org > > Sent: Monday, September 17, 2018 7:19:45 PM > > Subject: Re: [PATCH v2 2/2] docs: Note new requirement to include a SPDX > > line > > > > On Mon, 2018-09-17 at 18:17 +0100, Stephen Finucane wrote: > > > Add some wording around the requirement to include this line instead > > > of > > > the license header. Also note the requirement that all code be > > > GPLv2-licensed and add a CONTRIBUTING document, which GitHub likes. > > > > > > Signed-off-by: Stephen Finucane > > > Cc: Daniel Axtens > > > > Looks like patch 1/2 (or the earlier v1 rendition) didn't make it to > > the list. It's basically the following diff for all files: > > > >-# This file is part of the Patchwork package. > >-# > >-# Patchwork is free software; you can redistribute it and/or modify > >-# it under the terms of the GNU General Public License as published by > >-# the Free Software Foundation; either version 2 of the License, or > >-# (at your option) any later version. > >-# > >-# Patchwork is distributed in the hope that it will be useful, > >-# but WITHOUT ANY WARRANTY; without even the implied warranty of > >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > >-# GNU General Public License for more details. > >-# > >-# You should have received a copy of the GNU General Public License > >-# along with Patchwork; if not, write to the Free Software > >-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 > >USA > >+# SPDX-License-Identifier: GPL-2.0 > > > > This seems to be the same problem why my first tagging patch didn't make it > to the list - the email is too large and doesn't fit the mailing list > thresholds. Given how many files contain the preamble, the patch would need > to be split a lot to get it to the list. Yup, that's what I'm thinking. It's trivial though so unless anyone else wants to review this though, I'll just wait for Daniel to take a look and then merge it. Stephen > Veronika > > > Stephen > > > > ___ > > Patchwork mailing list > > Patchwork@lists.ozlabs.org > > https://lists.ozlabs.org/listinfo/patchwork > > ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
Re: [PATCH v2 2/2] docs: Note new requirement to include a SPDX line
- Original Message - > From: "Stephen Finucane" > To: patchwork@lists.ozlabs.org > Sent: Monday, September 17, 2018 7:19:45 PM > Subject: Re: [PATCH v2 2/2] docs: Note new requirement to include a SPDX line > > On Mon, 2018-09-17 at 18:17 +0100, Stephen Finucane wrote: > > Add some wording around the requirement to include this line instead > > of > > the license header. Also note the requirement that all code be > > GPLv2-licensed and add a CONTRIBUTING document, which GitHub likes. > > > > Signed-off-by: Stephen Finucane > > Cc: Daniel Axtens > > Looks like patch 1/2 (or the earlier v1 rendition) didn't make it to > the list. It's basically the following diff for all files: > >-# This file is part of the Patchwork package. >-# >-# Patchwork is free software; you can redistribute it and/or modify >-# it under the terms of the GNU General Public License as published by >-# the Free Software Foundation; either version 2 of the License, or >-# (at your option) any later version. >-# >-# Patchwork is distributed in the hope that it will be useful, >-# but WITHOUT ANY WARRANTY; without even the implied warranty of >-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >-# GNU General Public License for more details. >-# >-# You should have received a copy of the GNU General Public License >-# along with Patchwork; if not, write to the Free Software >-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 >USA >+# SPDX-License-Identifier: GPL-2.0 > This seems to be the same problem why my first tagging patch didn't make it to the list - the email is too large and doesn't fit the mailing list thresholds. Given how many files contain the preamble, the patch would need to be split a lot to get it to the list. Veronika > Stephen > > ___ > Patchwork mailing list > Patchwork@lists.ozlabs.org > https://lists.ozlabs.org/listinfo/patchwork > ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
Re: [PATCH v2 2/2] docs: Note new requirement to include a SPDX line
On Mon, 2018-09-17 at 18:17 +0100, Stephen Finucane wrote: > Add some wording around the requirement to include this line instead > of > the license header. Also note the requirement that all code be > GPLv2-licensed and add a CONTRIBUTING document, which GitHub likes. > > Signed-off-by: Stephen Finucane > Cc: Daniel Axtens Looks like patch 1/2 (or the earlier v1 rendition) didn't make it to the list. It's basically the following diff for all files: -# This file is part of the Patchwork package. -# -# Patchwork is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2 of the License, or -# (at your option) any later version. -# -# Patchwork is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Patchwork; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# SPDX-License-Identifier: GPL-2.0 Stephen ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH v2 2/2] docs: Note new requirement to include a SPDX line
Add some wording around the requirement to include this line instead of the license header. Also note the requirement that all code be GPLv2-licensed and add a CONTRIBUTING document, which GitHub likes. Signed-off-by: Stephen Finucane Cc: Daniel Axtens --- CONTRIBUTING.rst | 6 ++ docs/development/contributing.rst | 20 +--- 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 CONTRIBUTING.rst diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index ..131e2dcb --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,6 @@ +Contributing + + +For guidelines on contributing, refer to the `contributors documentation`__. + +__ https://patchwork.readthedocs.io/en/latest/development/contributing/ diff --git a/docs/development/contributing.rst b/docs/development/contributing.rst index 7e2a72cf..bada3938 100644 --- a/docs/development/contributing.rst +++ b/docs/development/contributing.rst @@ -4,13 +4,25 @@ Contributing Coding Standards -**Follow PEP8**. All code is currently PEP8 compliant and it should stay this -way. +**Follow PEP8**. All code is currently `PEP 8`_ compliant and it should stay +this way. + +All code must be GPLv2 licensed and must have a `SPDX License Identifier`_ +stating this. A copyright line should be included on new files and may be added +for significant changes to existing files. + +.. code-block:: python + + # Patchwork - automated patch tracking system + # Copyright (C) 2000 Jane Doe + # Copyright (C) 2001 Joe Bloggs + # + # SPDX-License-Identifier: GPL-2.0 Changes that fix semantic issues will be generally be happily received, but please keep such changes separate from functional changes. -`pep8` targets are provided via tox. Refer to the :ref:`testing` section +``pep8`` targets are provided via tox. Refer to the :ref:`testing` section below for more information on usage of this tool. .. _testing: @@ -148,6 +160,8 @@ announcements. Further information about the Patchwork mailing list is available can be found on `lists.ozlabs.org`_. +.. _PEP 8: https://pep8.org/ +.. _SPDX License Identifier: https://spdx.org/using-spdx-license-identifier .. _tox: https://tox.readthedocs.io/en/latest/ .. _reno: https://docs.openstack.org/developer/reno/ .. _QEMU guidelines: http://wiki.qemu.org/Contribute/SubmitAPatch -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH v2 2/4] tagging: add tags and related filters to REST API
From: Veronika Kabatova Signed-off-by: Veronika Kabatova --- patchwork/api/comment.py | 12 +- patchwork/api/cover.py| 14 ++- patchwork/api/filters.py | 42 ++- patchwork/api/patch.py| 13 +++--- patchwork/tests/api/test_patch.py | 3 +- .../tagging-rework-9907e9dc3f835566.yaml | 11 + 6 files changed, 85 insertions(+), 10 deletions(-) diff --git a/patchwork/api/comment.py b/patchwork/api/comment.py index 5a5adb1d..a328e2a8 100644 --- a/patchwork/api/comment.py +++ b/patchwork/api/comment.py @@ -26,6 +26,7 @@ from patchwork.api.base import BaseHyperlinkedModelSerializer from patchwork.api.base import PatchworkPermission from patchwork.api.embedded import PersonSerializer from patchwork.models import Comment +from patchwork.models import SubmissionTag class CommentListSerializer(BaseHyperlinkedModelSerializer): @@ -34,6 +35,7 @@ class CommentListSerializer(BaseHyperlinkedModelSerializer): subject = SerializerMethodField() headers = SerializerMethodField() submitter = PersonSerializer(read_only=True) +tags = SerializerMethodField() def get_web_url(self, instance): request = self.context.get('request') @@ -43,6 +45,13 @@ class CommentListSerializer(BaseHyperlinkedModelSerializer): return email.parser.Parser().parsestr(comment.headers, True).get('Subject', '') +def get_tags(self, instance): +tags = {} +for tag_object in instance.all_tags: +tags[tag_object.name] = instance.all_tags[tag_object] + +return tags + def get_headers(self, comment): headers = {} @@ -60,10 +69,11 @@ class CommentListSerializer(BaseHyperlinkedModelSerializer): class Meta: model = Comment fields = ('id', 'web_url', 'msgid', 'date', 'subject', 'submitter', - 'content', 'headers') + 'content', 'headers', 'tags') read_only_fields = fields versioned_fields = { '1.1': ('web_url', ), +'1.2': ('tags', ), } diff --git a/patchwork/api/cover.py b/patchwork/api/cover.py index 3a9fc003..191b8418 100644 --- a/patchwork/api/cover.py +++ b/patchwork/api/cover.py @@ -30,6 +30,7 @@ from patchwork.api.embedded import PersonSerializer from patchwork.api.embedded import ProjectSerializer from patchwork.api.embedded import SeriesSerializer from patchwork.models import CoverLetter +from patchwork.models import SubmissionTag class CoverLetterListSerializer(BaseHyperlinkedModelSerializer): @@ -40,6 +41,7 @@ class CoverLetterListSerializer(BaseHyperlinkedModelSerializer): mbox = SerializerMethodField() series = SeriesSerializer(read_only=True) comments = SerializerMethodField() +tags = SerializerMethodField() def get_web_url(self, instance): request = self.context.get('request') @@ -53,6 +55,13 @@ class CoverLetterListSerializer(BaseHyperlinkedModelSerializer): return self.context.get('request').build_absolute_uri( reverse('api-cover-comment-list', kwargs={'pk': cover.id})) +def get_tags(self, instance): +tags = {} +for tag_object in instance.all_tags: +tags[tag_object.name] = instance.all_tags[tag_object] + +return tags + def to_representation(self, instance): # NOTE(stephenfin): This is here to ensure our API looks the same even # after we changed the series-patch relationship from M:N to 1:N. It @@ -65,10 +74,11 @@ class CoverLetterListSerializer(BaseHyperlinkedModelSerializer): class Meta: model = CoverLetter fields = ('id', 'url', 'web_url', 'project', 'msgid', 'date', 'name', - 'submitter', 'mbox', 'series', 'comments') + 'submitter', 'mbox', 'series', 'comments', 'tags') read_only_fields = fields versioned_fields = { '1.1': ('web_url', 'mbox', 'comments'), +'1.2': ('tags', ), } extra_kwargs = { 'url': {'view_name': 'api-cover-detail'}, @@ -113,6 +123,7 @@ class CoverLetterList(ListAPIView): def get_queryset(self): return CoverLetter.objects.all()\ +.prefetch_related('tags')\ .select_related('project', 'submitter', 'series')\ .defer('content', 'headers') @@ -124,4 +135,5 @@ class CoverLetterDetail(RetrieveAPIView): def get_queryset(self): return CoverLetter.objects.all()\ +.prefetch_related('tags')\ .select_related('project', 'submitter', 'series') diff --git a/patchwork/api/filters.py b/patchwork/api/filters.py index ddf527fd..416136e4 100644 --- a/patchwork/api/filters.py +++ b/patchwork/api/filters.py @@ -21,6 +21,7 @@ from django.contrib.auth.models import User from django.core.exceptions
[PATCH v2 4/4] tagging: change wording in documentation
From: Veronika Kabatova All submissions can have tags associated with them now and the documentation text should reflect it. Signed-off-by: Veronika Kabatova --- docs/usage/overview.rst | 9 + 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/docs/usage/overview.rst b/docs/usage/overview.rst index e84e13d9..91d710c0 100644 --- a/docs/usage/overview.rst +++ b/docs/usage/overview.rst @@ -119,10 +119,11 @@ one delegate can be assigned to a patch. Tags -Tags are specially formatted metadata appended to the foot the body of a patch -or a comment on a patch. Patchwork extracts these tags at parse time and -associates them with the patch. You add extra tags to an email by replying to -the email. The following tags are available on a standard Patchwork install: +Tags are specially formatted metadata appended to the foot the body of a patch, +cover letter or a comment related to them. Patchwork extracts these tags at +parse time and associates them with the submissions. You add extra tags to an +email by replying to the email. The following tags are available on a standard +Patchwork install: ``Acked-by:`` For example:: -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH v2 3/4] tagging: use tag infrastructure to create tags in mboxes
From: Veronika Kabatova Signed-off-by: Veronika Kabatova --- patchwork/models.py | 12 patchwork/tests/test_mboxviews.py | 19 --- patchwork/views/utils.py | 9 ++--- .../tagging-rework-9907e9dc3f835566.yaml | 3 +++ 4 files changed, 25 insertions(+), 18 deletions(-) diff --git a/patchwork/models.py b/patchwork/models.py index 5caf7641..a7c75e63 100644 --- a/patchwork/models.py +++ b/patchwork/models.py @@ -284,18 +284,6 @@ class EmailMixin(models.Model): submitter = models.ForeignKey(Person, on_delete=models.CASCADE) content = models.TextField(null=True, blank=True) -response_re = re.compile( -r'^(Tested|Reviewed|Acked|Signed-off|Nacked|Reported)-by:.*$', -re.M | re.I) - -@property -def patch_responses(self): -if not self.content: -return '' - -return ''.join([match.group(0) + '\n' for match in -self.response_re.finditer(self.content)]) - def _extract_tags(self, tags): found_tags = {} if not self.content: diff --git a/patchwork/tests/test_mboxviews.py b/patchwork/tests/test_mboxviews.py index 9d941bf8..f7be7b0e 100644 --- a/patchwork/tests/test_mboxviews.py +++ b/patchwork/tests/test_mboxviews.py @@ -36,9 +36,10 @@ from patchwork.tests.utils import create_user class MboxPatchResponseTest(TestCase): - """Test that the mbox view appends the Acked-by from a patch comment.""" +fixtures = ['default_tags'] + def setUp(self): self.project = create_project() self.person = create_person() @@ -53,7 +54,9 @@ class MboxPatchResponseTest(TestCase): submitter=self.person, content='comment 2 text\nAcked-by: 2\n') response = self.client.get(reverse('patch-mbox', args=[patch.id])) -self.assertContains(response, 'Acked-by: 1\nAcked-by: 2\n') +# Can't guarantee the order in which the tags are returned +self.assertContains(response, 'Acked-by: 1\n') +self.assertContains(response, 'Acked-by: 2\n') def test_patch_utf8_nbsp(self): patch = create_patch( @@ -73,6 +76,8 @@ class MboxPatchSplitResponseTest(TestCase): """Test that the mbox view appends the Acked-by from a patch comment, and places it before an '---' update line.""" +fixtures = ['default_tags'] + def setUp(self): project = create_project() self.person = create_person() @@ -88,7 +93,15 @@ class MboxPatchSplitResponseTest(TestCase): def test_patch_response(self): response = self.client.get(reverse('patch-mbox', args=[self.patch.id])) -self.assertContains(response, 'Acked-by: 1\nAcked-by: 2\n') +# Can't guarantee the order in which the tags are returned +self.assertContains(response, 'Acked-by: 1\n') +self.assertContains(response, 'Acked-by: 2\n') +# We need to check for 3 Acked-by strings, one comes from the body of +# the patch and the other two are the tags themselves. +self.assertRegex( +response.content.decode(), +'(?s).*Acked-by: 1\n.*Acked-by.*Acked-by.*---\nupdate.*' +) class MboxHeaderTest(TestCase): diff --git a/patchwork/views/utils.py b/patchwork/views/utils.py index 4644c621..0586265b 100644 --- a/patchwork/views/utils.py +++ b/patchwork/views/utils.py @@ -27,11 +27,13 @@ import email.utils import re from django.conf import settings +from django.db.models import Q from django.http import Http404 from django.utils import six from patchwork.models import Comment from patchwork.models import Patch +from patchwork.models import SubmissionTag if settings.ENABLE_REST_API: from rest_framework.authtoken.models import Token @@ -74,9 +76,10 @@ def _submission_to_mbox(submission): else: postscript = '' -# TODO(stephenfin): Make this use the tags infrastructure -for comment in Comment.objects.filter(submission=submission): -body += comment.patch_responses +for (tagname, value) in SubmissionTag.objects.filter( +Q(submission=submission) | Q(series=submission.series) +).values_list('tag__name', 'value').distinct(): +body += '%s: %s\n' % (tagname, value) if postscript: body += '---\n' + postscript + '\n' diff --git a/releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml b/releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml index fdfd39f0..7fd64184 100644 --- a/releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml +++ b/releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml @@ -24,3 +24,6 @@ upgrade: the actual tag data will be created by the command, to make the migration itself faster. Please note that this will take a lot of time and based on the size of the data in question, might be useful to run in batches. +other: + - | +The tagging feature is now used to
[PATCH v2 1/4] Rework tagging infrastructure
From: Veronika Kabatova Solve #113 and #57 GitHub issues, keep track of tag origin to be able to add tags to comments in the API later. Use relations Tag-Patch and Tag-CoverLetter to avoid duplication of tags for each patch in series, and use `series` attribute of SubmissionTag as a notion of a tag which is related to each patch in the series (because it comes from cover letter or it's comments) Signed-off-by: Veronika Kabatova --- Rebased on top of 'Convert Series-Patch relationship to 1:N' series. Stephen, I split up the patch to separate out API, mbox and documentation changes as you suggested; and implemented your comments (simplified the migration in favor of running the retag comment, moved the tag retrieval from the API into a property in models.py, added comment and tag prefetching, increased the API version where needed, added wildcard to API filter and simplified it and some other minor things). The series-patch cleanup definitely helped with some cleanup, but let me know if there are other optimizations that would help with regards to DB performance. --- patchwork/management/commands/retag.py| 15 +- patchwork/migrations/0034_rework_tagging.py | 66 +++ patchwork/models.py | 175 -- patchwork/templatetags/patch.py | 3 +- patchwork/tests/test_parser.py| 18 +- patchwork/tests/test_tags.py | 64 +++ patchwork/views/__init__.py | 3 - .../tagging-rework-9907e9dc3f835566.yaml | 15 ++ 8 files changed, 202 insertions(+), 157 deletions(-) create mode 100644 patchwork/migrations/0034_rework_tagging.py create mode 100644 releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml diff --git a/patchwork/management/commands/retag.py b/patchwork/management/commands/retag.py index 8617ff41..95b2cc1f 100644 --- a/patchwork/management/commands/retag.py +++ b/patchwork/management/commands/retag.py @@ -19,15 +19,15 @@ from django.core.management.base import BaseCommand -from patchwork.models import Patch +from patchwork.models import Submission class Command(BaseCommand): -help = 'Update the tag (Ack/Review/Test) counts on existing patches' -args = '[...]' +help = 'Update tags on existing submissions and associated comments' +args = '[...]' def handle(self, *args, **options): -query = Patch.objects +query = Submission.objects.prefetch_related('comments') if args: query = query.filter(id__in=args) @@ -36,8 +36,11 @@ class Command(BaseCommand): count = query.count() -for i, patch in enumerate(query.iterator()): -patch.refresh_tag_counts() +for i, submission in enumerate(query.iterator()): +submission.refresh_tags() +for comment in submission.comments.all(): +comment.refresh_tags() + if (i % 10) == 0: self.stdout.write('%06d/%06d\r' % (i, count), ending='') self.stdout.flush() diff --git a/patchwork/migrations/0034_rework_tagging.py b/patchwork/migrations/0034_rework_tagging.py new file mode 100644 index ..580a4fd0 --- /dev/null +++ b/patchwork/migrations/0034_rework_tagging.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +dependencies = [ +('patchwork', '0033_remove_patch_series_model'), +] + +operations = [ +migrations.CreateModel( +name='SubmissionTag', +fields=[ +('id', models.AutoField(auto_created=True, +primary_key=True, +serialize=False, +verbose_name='ID')), +('value', models.CharField(max_length=255)), +('comment', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Comment', +null=True +)), +('submission', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Submission' +)), +('tag', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Tag' +)), +('series', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Series', +null=True +)), +], +), +migrations.AlterUniqueTogether( +name='patchtag', +unique_together=set([]), +), +migrations.RemoveField(model_name='patchtag', name='patch',), +
[PATCH v2 1/4] Rework tagging infrastructure
From: Veronika Kabatova Solve #113 and #57 GitHub issues, keep track of tag origin to be able to add tags to comments in the API later. Use relations Tag-Patch and Tag-CoverLetter to avoid duplication of tags for each patch in series, and use `series` attribute of SubmissionTag as a notion of a tag which is related to each patch in the series (because it comes from cover letter or it's comments) Signed-off-by: Veronika Kabatova --- Rebased on top of 'Convert Series-Patch relationship to 1:N' series. Stephen, I split up the patch to separate out API, mbox and documentation changes as you suggested; and implemented your comments (simplified the migration in favor of running the retag comment, moved the tag retrieval from the API into a property in models.py, added comment and tag prefetching, increased the API version where needed, added wildcard to API filter and simplified it and some other minor things). The series-patch cleanup definitely helped with some cleanup, but let me know if there are other optimizations that would help with regards to DB performance. --- patchwork/management/commands/retag.py| 15 +- patchwork/migrations/0034_rework_tagging.py | 66 +++ patchwork/models.py | 175 -- patchwork/templatetags/patch.py | 3 +- patchwork/tests/test_parser.py| 18 +- patchwork/tests/test_tags.py | 64 +++ patchwork/views/__init__.py | 3 - .../tagging-rework-9907e9dc3f835566.yaml | 15 ++ 8 files changed, 202 insertions(+), 157 deletions(-) create mode 100644 patchwork/migrations/0034_rework_tagging.py create mode 100644 releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml diff --git a/patchwork/management/commands/retag.py b/patchwork/management/commands/retag.py index 8617ff41..95b2cc1f 100644 --- a/patchwork/management/commands/retag.py +++ b/patchwork/management/commands/retag.py @@ -19,15 +19,15 @@ from django.core.management.base import BaseCommand -from patchwork.models import Patch +from patchwork.models import Submission class Command(BaseCommand): -help = 'Update the tag (Ack/Review/Test) counts on existing patches' -args = '[...]' +help = 'Update tags on existing submissions and associated comments' +args = '[...]' def handle(self, *args, **options): -query = Patch.objects +query = Submission.objects.prefetch_related('comments') if args: query = query.filter(id__in=args) @@ -36,8 +36,11 @@ class Command(BaseCommand): count = query.count() -for i, patch in enumerate(query.iterator()): -patch.refresh_tag_counts() +for i, submission in enumerate(query.iterator()): +submission.refresh_tags() +for comment in submission.comments.all(): +comment.refresh_tags() + if (i % 10) == 0: self.stdout.write('%06d/%06d\r' % (i, count), ending='') self.stdout.flush() diff --git a/patchwork/migrations/0034_rework_tagging.py b/patchwork/migrations/0034_rework_tagging.py new file mode 100644 index ..580a4fd0 --- /dev/null +++ b/patchwork/migrations/0034_rework_tagging.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +dependencies = [ +('patchwork', '0033_remove_patch_series_model'), +] + +operations = [ +migrations.CreateModel( +name='SubmissionTag', +fields=[ +('id', models.AutoField(auto_created=True, +primary_key=True, +serialize=False, +verbose_name='ID')), +('value', models.CharField(max_length=255)), +('comment', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Comment', +null=True +)), +('submission', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Submission' +)), +('tag', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Tag' +)), +('series', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Series', +null=True +)), +], +), +migrations.AlterUniqueTogether( +name='patchtag', +unique_together=set([]), +), +migrations.RemoveField(model_name='patchtag', name='patch',), +
[PATCH v2 1/4] Rework tagging infrastructure
From: Veronika Kabatova Solve #113 and #57 GitHub issues, keep track of tag origin to be able to add tags to comments in the API later. Use relations Tag-Patch and Tag-CoverLetter to avoid duplication of tags for each patch in series, and use `series` attribute of SubmissionTag as a notion of a tag which is related to each patch in the series (because it comes from cover letter or it's comments) Signed-off-by: Veronika Kabatova --- Rebased on top of 'Convert Series-Patch relationship to 1:N' series. Stephen, I split up the patch to separate out API, mbox and documentation changes as you suggested; and implemented your comments (simplified the migration in favor of running the retag comment, moved the tag retrieval from the API into a property in models.py, added comment and tag prefetching, increased the API version where needed, added wildcard to API filter and simplified it and some other minor things). The series-patch cleanup definitely helped with some cleanup, but let me know if there are other optimizations that would help with regards to DB performance. --- patchwork/management/commands/retag.py| 15 +- patchwork/migrations/0034_rework_tagging.py | 66 +++ patchwork/models.py | 175 -- patchwork/templatetags/patch.py | 3 +- patchwork/tests/test_parser.py| 18 +- patchwork/tests/test_tags.py | 64 +++ patchwork/views/__init__.py | 3 - .../tagging-rework-9907e9dc3f835566.yaml | 15 ++ 8 files changed, 202 insertions(+), 157 deletions(-) create mode 100644 patchwork/migrations/0034_rework_tagging.py create mode 100644 releasenotes/notes/tagging-rework-9907e9dc3f835566.yaml diff --git a/patchwork/management/commands/retag.py b/patchwork/management/commands/retag.py index 8617ff41..95b2cc1f 100644 --- a/patchwork/management/commands/retag.py +++ b/patchwork/management/commands/retag.py @@ -19,15 +19,15 @@ from django.core.management.base import BaseCommand -from patchwork.models import Patch +from patchwork.models import Submission class Command(BaseCommand): -help = 'Update the tag (Ack/Review/Test) counts on existing patches' -args = '[...]' +help = 'Update tags on existing submissions and associated comments' +args = '[...]' def handle(self, *args, **options): -query = Patch.objects +query = Submission.objects.prefetch_related('comments') if args: query = query.filter(id__in=args) @@ -36,8 +36,11 @@ class Command(BaseCommand): count = query.count() -for i, patch in enumerate(query.iterator()): -patch.refresh_tag_counts() +for i, submission in enumerate(query.iterator()): +submission.refresh_tags() +for comment in submission.comments.all(): +comment.refresh_tags() + if (i % 10) == 0: self.stdout.write('%06d/%06d\r' % (i, count), ending='') self.stdout.flush() diff --git a/patchwork/migrations/0034_rework_tagging.py b/patchwork/migrations/0034_rework_tagging.py new file mode 100644 index ..580a4fd0 --- /dev/null +++ b/patchwork/migrations/0034_rework_tagging.py @@ -0,0 +1,66 @@ +# -*- coding: utf-8 -*- +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + +dependencies = [ +('patchwork', '0033_remove_patch_series_model'), +] + +operations = [ +migrations.CreateModel( +name='SubmissionTag', +fields=[ +('id', models.AutoField(auto_created=True, +primary_key=True, +serialize=False, +verbose_name='ID')), +('value', models.CharField(max_length=255)), +('comment', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Comment', +null=True +)), +('submission', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Submission' +)), +('tag', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Tag' +)), +('series', models.ForeignKey( +on_delete=django.db.models.deletion.CASCADE, +to='patchwork.Series', +null=True +)), +], +), +migrations.AlterUniqueTogether( +name='patchtag', +unique_together=set([]), +), +migrations.RemoveField(model_name='patchtag', name='patch',), +
[PATCH 6/6] views: Add error handling for user registration
This was already present for registration confirmation but missing for initial registration. Resolve this. Signed-off-by: Stephen Finucane --- patchwork/views/user.py | 15 +-- 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/patchwork/views/user.py b/patchwork/views/user.py index 6348bed6..9876da96 100644 --- a/patchwork/views/user.py +++ b/patchwork/views/user.py @@ -64,6 +64,8 @@ def register(request): email=user.email) conf.save() +context['confirmation'] = conf + # send email subject = render_to_string( 'patchwork/mails/activation-subject.txt') @@ -71,12 +73,13 @@ def register(request): 'patchwork/mails/activation.txt', {'site': Site.objects.get_current(), 'confirmation': conf}) -# TODO(stephenfin): Should this be surrounded by a try-except? -send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, - [conf.email]) - -# setting 'confirmation' in the template indicates success -context['confirmation'] = conf +try: +send_mail(subject, message, settings.DEFAULT_FROM_EMAIL, + [conf.email]) +except smtplib.SMTPException: +context['confirmation'] = None +context['error'] = ('An error occurred during registration. ' +'Please try again later') else: form = RegistrationForm() -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH 5/6] templates: Remove 'email_sent' attribute
Further normalization to ensure all related code paths use similar code. Signed-off-by: Stephen Finucane --- patchwork/templates/patchwork/optin-request.html | 2 +- patchwork/templates/patchwork/optout-request.html | 2 +- patchwork/tests/test_mail_settings.py | 8 patchwork/views/mail.py | 7 +++ 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/patchwork/templates/patchwork/optin-request.html b/patchwork/templates/patchwork/optin-request.html index dfc104e8..90963e65 100644 --- a/patchwork/templates/patchwork/optin-request.html +++ b/patchwork/templates/patchwork/optin-request.html @@ -4,7 +4,7 @@ {% block heading %}Opt-in{% endblock %} {% block body %} -{% if email_sent %} +{% if confirmation %} Opt-in confirmation email sent An opt-in confirmation mail has been sent to {{confirmation.email}}, containing a link. Please click on diff --git a/patchwork/templates/patchwork/optout-request.html b/patchwork/templates/patchwork/optout-request.html index eae05e62..659af773 100644 --- a/patchwork/templates/patchwork/optout-request.html +++ b/patchwork/templates/patchwork/optout-request.html @@ -4,7 +4,7 @@ {% block heading %}Opt-out{% endblock %} {% block body %} -{% if email_sent %} +{% if confirmation %} Opt-out confirmation email sent An opt-out confirmation mail has been sent to {{confirmation.email}}, containing a link. Please click on diff --git a/patchwork/tests/test_mail_settings.py b/patchwork/tests/test_mail_settings.py index 70e135d5..8844212e 100644 --- a/patchwork/tests/test_mail_settings.py +++ b/patchwork/tests/test_mail_settings.py @@ -108,7 +108,7 @@ class OptoutRequestTest(TestCase): self.assertFormError(response, 'form', 'email', 'This field is required.') self.assertTrue(response.context['error']) -self.assertNotIn('email_sent', response.context) +self.assertNotIn('confirmation', response.context) self.assertEqual(len(mail.outbox), 0) def test_post_non_email(self): @@ -116,7 +116,7 @@ class OptoutRequestTest(TestCase): self.assertEqual(response.status_code, 200) self.assertFormError(response, 'form', 'email', error_strings['email']) self.assertTrue(response.context['error']) -self.assertNotIn('email_sent', response.context) +self.assertNotIn('confirmation', response.context) self.assertEqual(len(mail.outbox), 0) @@ -189,7 +189,7 @@ class OptinRequestTest(TestCase): self.assertFormError(response, 'form', 'email', 'This field is required.') self.assertTrue(response.context['error']) -self.assertNotIn('email_sent', response.context) +self.assertNotIn('confirmation', response.context) self.assertEqual(len(mail.outbox), 0) def test_post_non_email(self): @@ -197,7 +197,7 @@ class OptinRequestTest(TestCase): self.assertEqual(response.status_code, 200) self.assertFormError(response, 'form', 'email', error_strings['email']) self.assertTrue(response.context['error']) -self.assertNotIn('email_sent', response.context) +self.assertNotIn('confirmation', response.context) self.assertEqual(len(mail.outbox), 0) diff --git a/patchwork/views/mail.py b/patchwork/views/mail.py index 1ce37736..6a3c1c25 100644 --- a/patchwork/views/mail.py +++ b/patchwork/views/mail.py @@ -97,8 +97,8 @@ def _optinout(request, action): return render(request, html_template, context) email = form.cleaned_data['email'] -if action == 'optin' and \ -EmailOptout.objects.filter(email=email).count() == 0: +if action == 'optin' and EmailOptout.objects.filter( +email=email).count() == 0: context['error'] = ("The email address %s is not on the patchwork " "opt-out list, so you don't need to opt back in" % email) @@ -115,9 +115,8 @@ def _optinout(request, action): try: send_mail(subject, message, conf_settings.DEFAULT_FROM_EMAIL, [email]) -# TODO(stephenfin): This is unnecessary and can be removed -context['email_sent'] = True except smtplib.SMTPException: +context['confirmation'] = None context['error'] = ('An error occurred during confirmation . ' 'Please try again later.') context['admins'] = conf_settings.ADMINS -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH 4/6] templates: Move additional email subjects to templates
Use a uniform pattern for this stuff. Signed-off-by: Stephen Finucane --- .../patchwork/mails/optin-request-subject.txt | 1 + .../mails/optout-request-subject.txt | 1 + .../patchwork/mails/user-link-subject.txt | 1 + patchwork/views/mail.py | 19 +++ patchwork/views/user.py | 2 +- 5 files changed, 15 insertions(+), 9 deletions(-) create mode 100644 patchwork/templates/patchwork/mails/optin-request-subject.txt create mode 100644 patchwork/templates/patchwork/mails/optout-request-subject.txt create mode 100644 patchwork/templates/patchwork/mails/user-link-subject.txt diff --git a/patchwork/templates/patchwork/mails/optin-request-subject.txt b/patchwork/templates/patchwork/mails/optin-request-subject.txt new file mode 100644 index ..9733b6f3 --- /dev/null +++ b/patchwork/templates/patchwork/mails/optin-request-subject.txt @@ -0,0 +1 @@ +Patchwork opt-in request \ No newline at end of file diff --git a/patchwork/templates/patchwork/mails/optout-request-subject.txt b/patchwork/templates/patchwork/mails/optout-request-subject.txt new file mode 100644 index ..377dfc89 --- /dev/null +++ b/patchwork/templates/patchwork/mails/optout-request-subject.txt @@ -0,0 +1 @@ +Patchwork opt-out confirmation \ No newline at end of file diff --git a/patchwork/templates/patchwork/mails/user-link-subject.txt b/patchwork/templates/patchwork/mails/user-link-subject.txt new file mode 100644 index ..8ac4d1d4 --- /dev/null +++ b/patchwork/templates/patchwork/mails/user-link-subject.txt @@ -0,0 +1 @@ +Patchwork email address confirmation \ No newline at end of file diff --git a/patchwork/views/mail.py b/patchwork/views/mail.py index 12825a13..1ce37736 100644 --- a/patchwork/views/mail.py +++ b/patchwork/views/mail.py @@ -80,9 +80,10 @@ def optin_confirm(request, conf): return render(request, 'patchwork/optin.html', context) -def _optinout(request, action, description): +def _optinout(request, action): context = {} mail_template = 'patchwork/mails/%s-request.txt' % action +mail_subject_template = 'patchwork/mails/%s-request-subject.txt' % action html_template = 'patchwork/%s-request.html' % action if request.method != 'POST': @@ -90,8 +91,8 @@ def _optinout(request, action, description): form = EmailForm(data=request.POST) if not form.is_valid(): -context['error'] = ('There was an error in the %s form. Please ' -'review the form and re-submit.' % description) +context['error'] = ('There was an error in the form. Please review ' +'and re-submit.') context['form'] = form return render(request, html_template, context) @@ -108,11 +109,13 @@ def _optinout(request, action, description): conf.save() context['confirmation'] = conf -mail = render_to_string(mail_template, context, request=request) + +subject = render_to_string(mail_subject_template) +message = render_to_string(mail_template, context, request=request) try: -send_mail('Patchwork %s confirmation' % description, mail, - conf_settings.DEFAULT_FROM_EMAIL, [email]) +send_mail(subject, message, conf_settings.DEFAULT_FROM_EMAIL, [email]) +# TODO(stephenfin): This is unnecessary and can be removed context['email_sent'] = True except smtplib.SMTPException: context['error'] = ('An error occurred during confirmation . ' @@ -123,8 +126,8 @@ def _optinout(request, action, description): def optout(request): -return _optinout(request, 'optout', 'opt-out') +return _optinout(request, 'optout') def optin(request): -return _optinout(request, 'optin', 'opt-in') +return _optinout(request, 'optin') diff --git a/patchwork/views/user.py b/patchwork/views/user.py index cb8e61af..6348bed6 100644 --- a/patchwork/views/user.py +++ b/patchwork/views/user.py @@ -151,7 +151,7 @@ def link(request): context['confirmation'] = conf -subject = 'Patchwork email address confirmation', +subject = render_to_string('patchwork/mails/user-link-subject.txt') message = render_to_string('patchwork/mails/user-link.txt', context, request=request) try: -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH 2/6] templates: Rename additional templates
Make ALL the things consistent. Signed-off-by: Stephen Finucane --- .../{download_buttons.html => download-buttons.html} | 0 patchwork/templates/patchwork/{mail-form.html => mail.html} | 0 .../patchwork/{registration_form.html => registration.html} | 0 patchwork/templates/patchwork/submission.html | 4 ++-- patchwork/tests/test_mail_settings.py | 4 ++-- patchwork/tests/test_registration.py | 2 +- patchwork/views/mail.py | 2 +- patchwork/views/user.py | 2 +- 8 files changed, 7 insertions(+), 7 deletions(-) rename patchwork/templates/patchwork/{download_buttons.html => download-buttons.html} (100%) rename patchwork/templates/patchwork/{mail-form.html => mail.html} (100%) rename patchwork/templates/patchwork/{registration_form.html => registration.html} (100%) diff --git a/patchwork/templates/patchwork/download_buttons.html b/patchwork/templates/patchwork/download-buttons.html similarity index 100% rename from patchwork/templates/patchwork/download_buttons.html rename to patchwork/templates/patchwork/download-buttons.html diff --git a/patchwork/templates/patchwork/mail-form.html b/patchwork/templates/patchwork/mail.html similarity index 100% rename from patchwork/templates/patchwork/mail-form.html rename to patchwork/templates/patchwork/mail.html diff --git a/patchwork/templates/patchwork/registration_form.html b/patchwork/templates/patchwork/registration.html similarity index 100% rename from patchwork/templates/patchwork/registration_form.html rename to patchwork/templates/patchwork/registration.html diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html index f03e1408..6e189b27 100644 --- a/patchwork/templates/patchwork/submission.html +++ b/patchwork/templates/patchwork/submission.html @@ -28,7 +28,7 @@ function toggle_div(link_id, headers_id) {{ submission.name }} -{% include "patchwork/download_buttons.html" %} +{% include "patchwork/download-buttons.html" %} @@ -285,7 +285,7 @@ function toggle_div(link_id, headers_id) {% if submission.diff %} Patch - {% include "patchwork/download_buttons.html" %} + {% include "patchwork/download-buttons.html" %} diff --git a/patchwork/tests/test_mail_settings.py b/patchwork/tests/test_mail_settings.py index 6d56f5a8..70e135d5 100644 --- a/patchwork/tests/test_mail_settings.py +++ b/patchwork/tests/test_mail_settings.py @@ -46,14 +46,14 @@ class MailSettingsTest(TestCase): def test_post_empty(self): response = self.client.post(reverse('mail-settings'), {'email': ''}) self.assertEqual(response.status_code, 200) -self.assertTemplateUsed(response, 'patchwork/mail-form.html') +self.assertTemplateUsed(response, 'patchwork/mail.html') self.assertFormError(response, 'form', 'email', 'This field is required.') def test_post_invalid(self): response = self.client.post(reverse('mail-settings'), {'email': 'foo'}) self.assertEqual(response.status_code, 200) -self.assertTemplateUsed(response, 'patchwork/mail-form.html') +self.assertTemplateUsed(response, 'patchwork/mail.html') self.assertFormError(response, 'form', 'email', error_strings['email']) def test_post_optin(self): diff --git a/patchwork/tests/test_registration.py b/patchwork/tests/test_registration.py index 616254d2..ad8ead23 100644 --- a/patchwork/tests/test_registration.py +++ b/patchwork/tests/test_registration.py @@ -55,7 +55,7 @@ class RegistrationTest(TestCase): def test_registration_form(self): response = self.client.get('/register/') self.assertEqual(response.status_code, 200) -self.assertTemplateUsed(response, 'patchwork/registration_form.html') +self.assertTemplateUsed(response, 'patchwork/registration.html') def test_blank_fields(self): for field in ['username', 'email', 'password']: diff --git a/patchwork/views/mail.py b/patchwork/views/mail.py index 45283eba..12825a13 100644 --- a/patchwork/views/mail.py +++ b/patchwork/views/mail.py @@ -48,7 +48,7 @@ def settings(request): 'form': form, } -return render(request, 'patchwork/mail-form.html', context) +return render(request, 'patchwork/mail.html', context) def optout_confirm(request, conf): diff --git a/patchwork/views/user.py b/patchwork/views/user.py index 848f86e5..cb8e61af 100644 --- a/patchwork/views/user.py +++ b/patchwork/views/user.py @@ -82,7 +82,7 @@ def register(request): context['form'] = form -return render(request, 'patchwork/registration_form.html', context) +return render(request, 'patchwork/registration.html', context) def register_confirm(request, conf): -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org
[PATCH 3/6] templates: Keep only whole templates in the top-level
Again, this should make this a little more understandable as it ensures a rough mapping exists between views and template names. Signed-off-by: Stephen Finucane --- patchwork/templates/patchwork/bundle.html | 2 +- patchwork/templates/patchwork/list.html | 2 +- .../patchwork/{ => partials}/download-buttons.html | 0 patchwork/templates/patchwork/{ => partials}/filters.html | 0 .../templates/patchwork/{ => partials}/pagination.html | 0 .../templates/patchwork/{ => partials}/patch-list.html | 6 +++--- patchwork/templates/patchwork/submission.html | 4 ++-- patchwork/templates/patchwork/todo-list.html| 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) rename patchwork/templates/patchwork/{ => partials}/download-buttons.html (100%) rename patchwork/templates/patchwork/{ => partials}/filters.html (100%) rename patchwork/templates/patchwork/{ => partials}/pagination.html (100%) rename patchwork/templates/patchwork/{ => partials}/patch-list.html (98%) diff --git a/patchwork/templates/patchwork/bundle.html b/patchwork/templates/patchwork/bundle.html index 2042cb96..b5c9f90a 100644 --- a/patchwork/templates/patchwork/bundle.html +++ b/patchwork/templates/patchwork/bundle.html @@ -40,6 +40,6 @@ project. {% endif %} -{% include "patchwork/patch-list.html" %} +{% include "patchwork/partials/patch-list.html" %} {% endblock %} diff --git a/patchwork/templates/patchwork/list.html b/patchwork/templates/patchwork/list.html index 180c5607..5d3d82aa 100644 --- a/patchwork/templates/patchwork/list.html +++ b/patchwork/templates/patchwork/list.html @@ -18,6 +18,6 @@ while updating patches: {% endif %} -{% include "patchwork/patch-list.html" %} +{% include "patchwork/partials/patch-list.html" %} {% endblock %} diff --git a/patchwork/templates/patchwork/download-buttons.html b/patchwork/templates/patchwork/partials/download-buttons.html similarity index 100% rename from patchwork/templates/patchwork/download-buttons.html rename to patchwork/templates/patchwork/partials/download-buttons.html diff --git a/patchwork/templates/patchwork/filters.html b/patchwork/templates/patchwork/partials/filters.html similarity index 100% rename from patchwork/templates/patchwork/filters.html rename to patchwork/templates/patchwork/partials/filters.html diff --git a/patchwork/templates/patchwork/pagination.html b/patchwork/templates/patchwork/partials/pagination.html similarity index 100% rename from patchwork/templates/patchwork/pagination.html rename to patchwork/templates/patchwork/partials/pagination.html diff --git a/patchwork/templates/patchwork/patch-list.html b/patchwork/templates/patchwork/partials/patch-list.html similarity index 98% rename from patchwork/templates/patchwork/patch-list.html rename to patchwork/templates/patchwork/partials/patch-list.html index 71c1ba92..53d577de 100644 --- a/patchwork/templates/patchwork/patch-list.html +++ b/patchwork/templates/patchwork/partials/patch-list.html @@ -4,9 +4,9 @@ {% load project %} {% load static %} -{% include "patchwork/filters.html" %} +{% include "patchwork/partials/filters.html" %} -{% include "patchwork/pagination.html" %} +{% include "patchwork/partials/pagination.html" %} {% if order.editable %} @@ -218,7 +218,7 @@ $(document).ready(function() { {% if page.paginator.count %} -{% include "patchwork/pagination.html" %} +{% include "patchwork/partials/pagination.html" %} diff --git a/patchwork/templates/patchwork/submission.html b/patchwork/templates/patchwork/submission.html index 6e189b27..eb5e3583 100644 --- a/patchwork/templates/patchwork/submission.html +++ b/patchwork/templates/patchwork/submission.html @@ -28,7 +28,7 @@ function toggle_div(link_id, headers_id) {{ submission.name }} -{% include "patchwork/download-buttons.html" %} +{% include "patchwork/partials/download-buttons.html" %} @@ -285,7 +285,7 @@ function toggle_div(link_id, headers_id) {% if submission.diff %} Patch - {% include "patchwork/download-buttons.html" %} + {% include "patchwork/partials/download-buttons.html" %} diff --git a/patchwork/templates/patchwork/todo-list.html b/patchwork/templates/patchwork/todo-list.html index 444baa01..1ec2713d 100644 --- a/patchwork/templates/patchwork/todo-list.html +++ b/patchwork/templates/patchwork/todo-list.html @@ -12,6 +12,6 @@ are in an "action required" state ({% for state in action_required_states %}{% if forloop.last and not forloop.first %} or {% endif %}{{ state }}{% if not forloop.last and not forloop.first %}, {%endif %}{% endfor %}), and are not archived. -{% include "patchwork/patch-list.html" %} +{% include "patchwork/partials/patch-list.html" %} {% endblock %} -- 2.17.1 ___ Patchwork mailing list Patchwork@lists.ozlabs.org https://lists.ozlabs.org/listinfo/patchwork
[PATCH 1/6] templates: Move mails to separate directory
This makes things a little easier to parse. A couple of templates are renamed and the 'register.mail' template, which appears to be unused since commit f1e089f7, is removed. Signed-off-by: Stephen Finucane --- patchwork/notifications.py | 7 --- .../activation-subject.txt}| 0 .../{activation_email.txt => mails/activation.txt} | 0 .../optin-request.txt} | 0 .../optout-request.txt}| 0 .../patch-change-notification-subject.txt} | 0 .../patch-change-notification.txt} | 0 .../{user-link.mail => mails/user-link.txt}| 0 patchwork/templates/patchwork/register.mail| 11 --- patchwork/views/mail.py| 2 +- patchwork/views/user.py| 14 +- 11 files changed, 14 insertions(+), 20 deletions(-) rename patchwork/templates/patchwork/{activation_email_subject.txt => mails/activation-subject.txt} (100%) rename patchwork/templates/patchwork/{activation_email.txt => mails/activation.txt} (100%) rename patchwork/templates/patchwork/{optin-request.mail => mails/optin-request.txt} (100%) rename patchwork/templates/patchwork/{optout-request.mail => mails/optout-request.txt} (100%) rename patchwork/templates/patchwork/{patch-change-notification-subject.text => mails/patch-change-notification-subject.txt} (100%) rename patchwork/templates/patchwork/{patch-change-notification.mail => mails/patch-change-notification.txt} (100%) rename patchwork/templates/patchwork/{user-link.mail => mails/user-link.txt} (100%) delete mode 100644 patchwork/templates/patchwork/register.mail diff --git a/patchwork/notifications.py b/patchwork/notifications.py index 3ddd806b..45c081b9 100644 --- a/patchwork/notifications.py +++ b/patchwork/notifications.py @@ -76,10 +76,11 @@ def send_notifications(): } subject = render_to_string( -'patchwork/patch-change-notification-subject.text', +'patchwork/mails/patch-change-notification-subject.txt', context).strip() -content = render_to_string('patchwork/patch-change-notification.mail', - context) +content = render_to_string( +'patchwork/mails/patch-change-notification.txt', +context) message = EmailMessage(subject=subject, body=content, from_email=settings.NOTIFICATION_FROM_EMAIL, diff --git a/patchwork/templates/patchwork/activation_email_subject.txt b/patchwork/templates/patchwork/mails/activation-subject.txt similarity index 100% rename from patchwork/templates/patchwork/activation_email_subject.txt rename to patchwork/templates/patchwork/mails/activation-subject.txt diff --git a/patchwork/templates/patchwork/activation_email.txt b/patchwork/templates/patchwork/mails/activation.txt similarity index 100% rename from patchwork/templates/patchwork/activation_email.txt rename to patchwork/templates/patchwork/mails/activation.txt diff --git a/patchwork/templates/patchwork/optin-request.mail b/patchwork/templates/patchwork/mails/optin-request.txt similarity index 100% rename from patchwork/templates/patchwork/optin-request.mail rename to patchwork/templates/patchwork/mails/optin-request.txt diff --git a/patchwork/templates/patchwork/optout-request.mail b/patchwork/templates/patchwork/mails/optout-request.txt similarity index 100% rename from patchwork/templates/patchwork/optout-request.mail rename to patchwork/templates/patchwork/mails/optout-request.txt diff --git a/patchwork/templates/patchwork/patch-change-notification-subject.text b/patchwork/templates/patchwork/mails/patch-change-notification-subject.txt similarity index 100% rename from patchwork/templates/patchwork/patch-change-notification-subject.text rename to patchwork/templates/patchwork/mails/patch-change-notification-subject.txt diff --git a/patchwork/templates/patchwork/patch-change-notification.mail b/patchwork/templates/patchwork/mails/patch-change-notification.txt similarity index 100% rename from patchwork/templates/patchwork/patch-change-notification.mail rename to patchwork/templates/patchwork/mails/patch-change-notification.txt diff --git a/patchwork/templates/patchwork/user-link.mail b/patchwork/templates/patchwork/mails/user-link.txt similarity index 100% rename from patchwork/templates/patchwork/user-link.mail rename to patchwork/templates/patchwork/mails/user-link.txt diff --git a/patchwork/templates/patchwork/register.mail b/patchwork/templates/patchwork/register.mail deleted file mode 100644 index 51f3adfa.. --- a/patchwork/templates/patchwork/register.mail +++ /dev/null @@ -1,11 +0,0 @@ -Hi, - -This email is to confirm your account on the Patchwork patch-tracking -system. You can activate your account by visiting the url: - - http://{{site.domain}}{% url
[PATCH] Remove '__future__.absolute_import' imports
These were added as part of the Python 3 support series but are not required and can be safely removed. Signed-off-by: Stephen Finucane --- patchwork/admin.py | 2 -- patchwork/fields.py | 2 -- patchwork/filters.py | 2 -- patchwork/models.py | 2 -- patchwork/paginator.py | 2 -- patchwork/settings/dev.py| 2 -- patchwork/settings/production.example.py | 2 -- patchwork/templatetags/listurl.py| 2 -- patchwork/templatetags/patch.py | 2 -- patchwork/templatetags/person.py | 2 -- patchwork/templatetags/project.py| 2 -- patchwork/templatetags/syntax.py | 2 -- patchwork/tests/test_bundles.py | 2 -- patchwork/tests/test_completion.py | 2 -- patchwork/tests/test_detail.py | 2 -- patchwork/tests/test_list.py | 2 -- patchwork/views/xmlrpc.py| 2 -- 17 files changed, 34 deletions(-) diff --git a/patchwork/admin.py b/patchwork/admin.py index d5b9887e..a0799011 100644 --- a/patchwork/admin.py +++ b/patchwork/admin.py @@ -16,8 +16,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from django.contrib.auth.models import User diff --git a/patchwork/fields.py b/patchwork/fields.py index e229d5be..9ad2c3c7 100644 --- a/patchwork/fields.py +++ b/patchwork/fields.py @@ -17,8 +17,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - import hashlib from django.db import models diff --git a/patchwork/filters.py b/patchwork/filters.py index 778b0bbd..2bcf26a8 100644 --- a/patchwork/filters.py +++ b/patchwork/filters.py @@ -16,8 +16,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - from django.contrib.auth.models import User from django.utils.html import escape from django.utils.safestring import mark_safe diff --git a/patchwork/models.py b/patchwork/models.py index 734abce6..4e925160 100644 --- a/patchwork/models.py +++ b/patchwork/models.py @@ -17,8 +17,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - from collections import Counter from collections import OrderedDict import datetime diff --git a/patchwork/paginator.py b/patchwork/paginator.py index 6acc9030..0cc0ad20 100644 --- a/patchwork/paginator.py +++ b/patchwork/paginator.py @@ -16,8 +16,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - from django.conf import settings from django.core import paginator diff --git a/patchwork/settings/dev.py b/patchwork/settings/dev.py index 79148803..4bb5a93c 100644 --- a/patchwork/settings/dev.py +++ b/patchwork/settings/dev.py @@ -7,8 +7,6 @@ Design based on: http://www.revsys.com/blog/2014/nov/21/recommended-django-project-layout/ """ -from __future__ import absolute_import - from .base import * # noqa # diff --git a/patchwork/settings/production.example.py b/patchwork/settings/production.example.py index 0c7a88c0..f58896fc 100644 --- a/patchwork/settings/production.example.py +++ b/patchwork/settings/production.example.py @@ -7,8 +7,6 @@ Design based on: http://www.revsys.com/blog/2014/nov/21/recommended-django-project-layout/ """ -from __future__ import absolute_import - import os from .base import * # noqa diff --git a/patchwork/templatetags/listurl.py b/patchwork/templatetags/listurl.py index a0981dd3..dc76b157 100644 --- a/patchwork/templatetags/listurl.py +++ b/patchwork/templatetags/listurl.py @@ -16,8 +16,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - from django.conf import settings from django import template from django.urls import reverse diff --git a/patchwork/templatetags/patch.py b/patchwork/templatetags/patch.py index b97d492c..27d0bce7 100644 --- a/patchwork/templatetags/patch.py +++ b/patchwork/templatetags/patch.py @@ -17,8 +17,6 @@ # Patchwork; if not, write to the Free Software Foundation, Inc., 51 Franklin # Street, Fifth Floor, Boston, MA, 02110-1335, USA -from __future__ import absolute_import - from django import template from django.utils.safestring import mark_safe from django.template.defaultfilters import stringfilter diff --git a/patchwork/templatetags/person.py