示例#1
0
    def test_utf8_nbsp_tags(self):
        """Test that UTF-8 NBSP characters are correctly handled."""
        patch = create_patch(content='patch text\n')
        create_patch_comment(patch=patch,
                             content=u'comment\nAcked-by:\u00A0 foo')

        mbox = utils.patch_to_mbox(patch)
        self.assertIn(u'\u00A0 foo\n', mbox)
示例#2
0
    def test_tags(self):
        """Test that tags are taken from a patch comment."""
        patch = create_patch(content='comment 1 text\nAcked-by: 1\n')
        create_patch_comment(patch=patch,
                             content='comment 2 text\nAcked-by: 2\n')

        mbox = utils.patch_to_mbox(patch)
        self.assertIn('Acked-by: 1\nAcked-by: 2\n', mbox)
示例#3
0
    def test_multiple_content_types(self):
        """Test what happens when a patch and comment have different
        Content-Type headers."""

        _, patches, _ = self._parse_mbox('bugs-multiple-content-types.mbox',
                                         [0, 1, 1])

        patch = patches[0]
        self.assertEqual(patch_to_mbox(patch).count('Content-Type:'), 1)
示例#4
0
 def test_date_header(self):
     patch = create_patch()
     mbox = utils.patch_to_mbox(patch)
     mail = email.message_from_string(mbox)
     mail_date = dateutil.parser.parse(mail['Date'])
     # patch dates are all in UTC
     patch_date = patch.date.replace(tzinfo=dateutil.tz.tzutc(),
                                     microsecond=0)
     self.assertEqual(mail_date, patch_date)
示例#5
0
    def test_patchwork_submitter_header(self):
        """Validate inclusion of generated 'X-Patchwork-Submitter' header."""
        email = '*****@*****.**'
        from_header = f'From: Jon Doe <{email}>\n'
        person = create_person(name='Jonathon Doe', email=email)
        submitter_header = f'X-Patchwork-Submitter: {person.name} <{email}>'

        patch = create_patch(submitter=person, headers=from_header)

        mbox = utils.patch_to_mbox(patch)
        self.assertIn(from_header, mbox)
        self.assertIn(submitter_header, mbox)
示例#6
0
    def test_from_header(self):
        """Validate non-ascii 'From' header.

        Test that a person with characters outside ASCII in his name do
        produce correct From header. As RFC 2822 state we must retain
        the <*****@*****.**> format for the mail while the name part
        may be coded in some ways.
        """
        person = create_person(name=u'©ool guŷ')
        patch = create_patch(submitter=person)
        from_email = f'<{person.email}>'
        mbox = utils.patch_to_mbox(patch)
        self.assertIn(from_email, mbox)
示例#7
0
def patch_mbox(request, patch_id):
    patch = get_object_or_404(Patch, id=patch_id)
    series_id = request.GET.get('series')

    response = HttpResponse(content_type='text/plain')
    if series_id:
        response.write(series_patch_to_mbox(patch, series_id))
    else:
        response.write(patch_to_mbox(patch))
    response['Content-Disposition'] = 'attachment; filename=%s.patch' % (
        patch.filename)

    return response
示例#8
0
def patch_mbox(request, patch_id):
    patch = get_object_or_404(Patch, id=patch_id)
    series_id = request.GET.get('series')

    response = HttpResponse(content_type='text/plain')
    if series_id:
        response.write(series_patch_to_mbox(patch, series_id))
    else:
        response.write(patch_to_mbox(patch))
    response['Content-Disposition'] = 'attachment; filename=' + \
        patch.filename.replace(';', '').replace('\n', '')

    return response
示例#9
0
    def test_supplied_date_header(self):
        patch = create_patch()
        offset = 3 * 60 * 60  # 3 (hours) * 60 (minutes) * 60 (seconds)
        tz = dateutil.tz.tzoffset(None, offset)
        date = datetime.datetime.utcnow() - datetime.timedelta(days=1)
        date = date.replace(tzinfo=tz, microsecond=0)

        patch.headers = 'Date: %s\n' % date.strftime("%a, %d %b %Y %T %z")
        patch.save()

        mbox = utils.patch_to_mbox(patch)
        mail = email.message_from_string(mbox)
        mail_date = dateutil.parser.parse(mail['Date'])
        self.assertEqual(mail_date, date)
示例#10
0
def patch_mbox(request, project_id, msgid):
    db_msgid = ('<%s>' % msgid)
    project = get_object_or_404(Project, linkname=project_id)
    patch = get_object_or_404(Patch, project_id=project.id, msgid=db_msgid)
    series_id = request.GET.get('series')

    response = HttpResponse(content_type='text/plain; charset=utf-8')
    if series_id:
        response.write(series_patch_to_mbox(patch, series_id))
    else:
        response.write(patch_to_mbox(patch))
    response['Content-Disposition'] = 'attachment; filename=%s.patch' % (
        patch.filename)

    return response
示例#11
0
    def test_comment_unchanged(self):
        """Validate postscript part of mail is unchanged.

        Test that the mbox view doesn't change the postscript part of
        a mail. There where always a missing blank right after the
        postscript delimiter '---' and an additional newline right
        before.
        """
        content = 'some comment\n---\n some/file | 1 +\n'
        project = create_project()
        patch = create_patch(content=content, diff='', project=project)

        mbox = utils.patch_to_mbox(patch)

        self.assertIn(content, mbox)
        self.assertNotIn(content + '\n', mbox)
示例#12
0
    def test_dmarc_from_header(self):
        """Validate 'From' header is rewritten correctly when DMARC-munged.

        Test that when an email with a DMARC-munged From header is processed,
        the From header will be unmunged and the munged address will be saved
        as 'X-Patchwork-Original-From'.
        """
        orig_from_header = 'Person via List <*****@*****.**>'
        rewritten_from_header = 'Person <*****@*****.**>'
        project = create_project(listemail='*****@*****.**')
        person = create_person(name='Person', email='*****@*****.**')
        patch = create_patch(project=project,
                             headers='From: ' + orig_from_header,
                             submitter=person)
        mbox = utils.patch_to_mbox(patch)
        mail = email.message_from_string(mbox)
        self.assertEqual(mail['From'], rewritten_from_header)
        self.assertEqual(mail['X-Patchwork-Original-From'], orig_from_header)
示例#13
0
def patch_get_mbox(patch_id):
    """Get a patch by its ID in mbox format.

    Retrieve a patch matching a given patch ID, if any exists, and
    return in mbox format.

    Args:
        patch_id (int): The ID of the patch to retrieve.

    Returns:
        The serialized patch matching the ID, if any, in mbox format,
        else an empty string.
    """
    try:
        patch = Patch.objects.get(id=patch_id)
        return patch_to_mbox(patch)
    except Patch.DoesNotExist:
        return ''
示例#14
0
def patch_mbox(request, patch_id):
    patch = get_object_or_404(Patch, id=patch_id)
    series_id = request.GET.get('series')

    response = HttpResponse(content_type='text/plain')
    if series_id:
        if not patch.series:
            raise Http404('Patch does not have an associated series. This is '
                          'because the patch was processed with an older '
                          'version of Patchwork. It is not possible to '
                          'provide dependencies for this patch.')
        response.write(series_patch_to_mbox(patch, series_id))
    else:
        response.write(patch_to_mbox(patch))
    response['Content-Disposition'] = 'attachment; filename=%s.patch' % (
        patch.filename)

    return response
示例#15
0
def patch_mbox(request, patch_id):
    patch = get_object_or_404(Patch, id=patch_id)
    series_id = request.GET.get('series')

    response = HttpResponse(content_type='text/plain')
    if series_id:
        if not patch.series:
            raise Http404('Patch does not have an associated series. This is '
                          'because the patch was processed with an older '
                          'version of Patchwork. It is not possible to '
                          'provide dependencies for this patch.')
        response.write(series_patch_to_mbox(patch, series_id))
    else:
        response.write(patch_to_mbox(patch))
    response['Content-Disposition'] = 'attachment; filename=%s.patch' % (
        patch.filename)

    return response
示例#16
0
def patch_get_mbox(patch_id):
    """Get a patch by its ID in mbox format.

    Retrieve a patch matching a given patch ID, if any exists, and
    return in mbox format.

    Args:
        patch_id (int): The ID of the patch to retrieve.

    Returns:
        The serialized patch matching the ID, if any, in mbox format,
        else an empty string.
    """
    try:
        patch = Patch.objects.get(id=patch_id)
        return patch_to_mbox(patch)
    except Patch.DoesNotExist:
        return ''
示例#17
0
    def test_multiple_tags(self):
        """Test that the mbox view appends tags correct.

        Ensure the tags are extracted from a patch comment, and placed before
        an '---' update line.
        """
        self.project = create_project()
        self.person = create_person()
        self.patch = create_patch(
            project=self.project,
            submitter=self.person,
            diff='',
            content='comment 1 text\nAcked-by: 1\n---\nupdate\n')
        self.comment = create_patch_comment(
            patch=self.patch,
            submitter=self.person,
            content='comment 2 text\nAcked-by: 2\n')

        mbox = utils.patch_to_mbox(self.patch)
        self.assertIn('Acked-by: 1\nAcked-by: 2\n', mbox)
示例#18
0
    def handle(self, *args, **options):
        if options['projects']:
            projects = []
            for listid in options['projects']:
                try:
                    projects.append(Project.objects.get(listid=listid))
                except Project.DoesNotExist:
                    raise CommandError('Project not found: %s' % listid)
        else:
            projects = list(Project.objects.all())

        name = 'patchwork_dump_' + datetime.now().strftime('%Y_%m_%d_%H%M%S')

        if options['compress']:
            name += '.tar.gz'
            compress_level = 9
        else:
            name += '.tar'
            compress_level = 1

        self.stdout.write('Generating patch archive...')

        with tarfile.open(name, 'w:gz', compresslevel=compress_level) as tar:
            for i, project in enumerate(projects):
                self.stdout.write('Project %02d/%02d (%s)' %
                                  (i + 1, len(projects), project.linkname))

                with tempfile.NamedTemporaryFile(delete=False) as mbox:
                    patches = Patch.objects.filter(project=project)
                    count = patches.count()
                    for j, patch in enumerate(patches):
                        if not (j % 10):
                            self.stdout.write('%06d/%06d\r' % (j, count),
                                              ending='')
                            self.stdout.flush()

                        mbox.write(force_bytes(patch_to_mbox(patch) + '\n'))

                tar.add(mbox.name, arcname='%s.mbox' % project.linkname)

        self.stdout.write('Dumped patch archive to %r' % name)
示例#19
0
 def test_patchwork_id_header(self):
     """Validate inclusion of generated 'X-Patchwork-Id' header."""
     patch = create_patch()
     mbox = utils.patch_to_mbox(patch)
     self.assertIn('X-Patchwork-Id: %d' % patch.id, mbox)
示例#20
0
 def test_patchwork_delegate_header(self):
     """Validate inclusion of generated 'X-Patchwork-Delegate' header."""
     user = create_user()
     patch = create_patch(delegate=user)
     mbox = utils.patch_to_mbox(patch)
     self.assertIn('X-Patchwork-Delegate: %s' % user.email, mbox)
示例#21
0
 def _test_header_dropped(self, header):
     patch = create_patch(headers=header + '\n')
     mbox = utils.patch_to_mbox(patch)
     self.assertNotIn(header, mbox)
示例#22
0
 def _test_header_passthrough(self, header):
     patch = create_patch(headers=header + '\n')
     mbox = utils.patch_to_mbox(patch)
     self.assertIn(header, mbox)