Skip to content

Commit faa5043

Browse files
committed
issue2551232 - modify in-reply-to threading when multiple matches
if an email is missing an issue designator, in-reply-to threading is attempted. In this change if in-reply-to threading matches multiple issues, fall back to matching on subject. It used to just arbitrairly choose the first matching issue.
1 parent 1f04997 commit faa5043

File tree

4 files changed

+106
-17
lines changed

4 files changed

+106
-17
lines changed

CHANGES.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ Fixed:
4545
connection is open. (John Rouillard)
4646
- fix crash if postgresql native-fts backend is asked to index content
4747
with null bytes. (John Rouillard)
48+
- issue2551232 - modify in-reply-to threading when multiple matches
49+
Change how in-reply-to threading works in the mailgw. If there is
50+
more than one issue with a matching parent message, fall back to
51+
subject matching. See upgrading.txt for details. (John Rouillard)
4852

4953
Features:
5054

doc/upgrading.txt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,30 @@ are not used.)
169169
For details on WAL mode see `<https://www.sqlite.org/wal.html>`_
170170
and `<https://www.sqlite.org/pragma.html#pragma_journal_mode>`_.
171171

172+
Change in processing of In-Reply_to email header
173+
------------------------------------------------
174+
175+
Messages received via email usually include a ``[issue23]``
176+
designator in the subject line. This indicates what issue is
177+
being updated. If the designator is missing, Roundup tries
178+
to find the correct issue by using the in-reply-to email
179+
header.
180+
181+
The former code appends the new message to the first issue
182+
found with a message matching the in-reply-to
183+
header. Usually a message is associated with only one
184+
issue. However nothing in Roundup requires that.
185+
186+
In this release, the in-reply-to matching is disabled if
187+
there are multiple issues with the same message. In this
188+
case, subject matching is used to try to find the matching
189+
issue.
190+
191+
If you don't have messages assigned to multiple issues you
192+
will see no change. If you do have multi-linked messages
193+
this will hopefully result in better message->issue
194+
matching.
195+
172196
.. index:: Upgrading; 2.1.0 to 2.2.0
173197

174198
Migrating from 2.1.0 to 2.2.0

roundup/mailgw.py

Lines changed: 24 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -773,29 +773,36 @@ def get_nodeid(self):
773773
nodeid = self.matches['nodeid']
774774

775775
# try in-reply-to to match the message if there's no nodeid
776-
# FIXME: possible crash if message linked to multiple issues
777-
# Use the in-reply-to of the current message to find an id
778-
# for the message being replied to.
779-
# Then search the current class (probably issue) for an issue
780-
# that has the parent_message id in the issue's messages
781-
# property. Then use this id as the node to update. HOWEVER if
782-
# the reply to message is linked to multiple issues, I think
783-
# this blows up.
784-
# Linking a message to multiple issues can be used to group
785-
# issues so that an update on a child issue is also reflected
786-
# on a parent issue. As the parent and child may have different
787-
# nosy/watchers.
788-
776+
# If there are multiple matches for the in-reply-to, fall back
777+
# to title/subject match.
789778
inreplyto = self.message.get_header('in-reply-to') or ''
790779
if nodeid is None and inreplyto:
791780
parent_message = self.db.getclass('msg').stringFind(
792781
messageid=inreplyto)
793-
# FIXME: if a message is linked to multiple issues, can nodeid
794-
# be a list? If so, will this crash??
795782
if parent_message:
796783
nodeid = self.cl.filter(None,
797-
{'messages': parent_message})[0]
798-
784+
{'messages': parent_message})
785+
if len(nodeid) == 1:
786+
nodeid = nodeid[0]
787+
elif nodeid: # len(nodeid) > 1
788+
# This message is responding to a message
789+
# we know about. But there is more than 1 issue
790+
# associated with it.
791+
# Before bouncing it or creating a new issue,
792+
# force it to be treated as a reply even if the Subject
793+
# is missing 'Re:'
794+
# Note that multiple issues may be matched by
795+
# Subject as well. The code chooses the most
796+
# recently updated. Hopefully Subjects have
797+
# less of a chance of collision. Possible future
798+
# idea filter ids that match subject by id's
799+
# that match in-reply-to and choose newest
800+
# match. Not sure if this would work better in
801+
# production, so not implementing now.
802+
nodeid = None
803+
# trigger Subject match
804+
self.matches['refwd'] = True
805+
799806
# but we do need either a title or a nodeid...
800807
if nodeid is None and not title:
801808
raise MailUsageError(_("""

test/test_mailgw.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4204,6 +4204,60 @@ def testReplytoMatch(self):
42044204
self.assertEqual(nodeid, nodeid2)
42054205
self.assertEqual(nodeid, nodeid3)
42064206

4207+
4208+
def testReplytoMultiMatch(self):
4209+
""" If an in reply-to header matches more than 1 issue:
4210+
Try a subject match, if that fails create a new issue.
4211+
"""
4212+
4213+
# create two issues with the same initial message/messgage-id.
4214+
nodeid1 = self.doNewIssue()
4215+
nodeid2 = self.doNewIssue()
4216+
4217+
# set unique title/subject for second issue.
4218+
self.db.issue.set("2", title="Testing1...")
4219+
4220+
# Send an email that will match both issue1 and issue2 by
4221+
# in-reply-to. As a result we fall back to Subject match, but
4222+
# the Subject doesn't match issue1 or 2. So it creates a new
4223+
# issue.
4224+
nodeid3 = self._handle_mail('''Content-Type: text/plain;
4225+
charset="iso-8859-1"
4226+
From: Chef <[email protected]>
4227+
4228+
Message-Id: <dummy_test_message_id2>
4229+
In-Reply-To: <dummy_test_message_id>
4230+
Subject: Testing2...
4231+
4232+
Followup message.
4233+
''')
4234+
# this will be added to issue3 because of in-reply-to.
4235+
nodeid4 = self._handle_mail('''Content-Type: text/plain;
4236+
charset="iso-8859-1"
4237+
From: Chef <[email protected]>
4238+
4239+
Message-Id: <dummy_test_message_id3>
4240+
In-Reply-To: <dummy_test_message_id2>
4241+
Subject: Testing...
4242+
4243+
Yet another message in the same thread/issue.
4244+
''')
4245+
4246+
# this message gets added to issue 2 by subject match.
4247+
nodeid5 = self._handle_mail('''Content-Type: text/plain;
4248+
charset="iso-8859-1"
4249+
From: Chef <[email protected]>
4250+
4251+
Message-Id: <dummy_test_message_id4>
4252+
In-Reply-To: <dummy_test_message_id>
4253+
Subject: Testing1...
4254+
4255+
Yet another message in the same thread/issue.
4256+
''')
4257+
4258+
self.assertEqual(nodeid3, nodeid4)
4259+
self.assertEqual(nodeid2, nodeid5)
4260+
42074261
def testHelpSubject(self):
42084262
message = '''Content-Type: text/plain;
42094263
charset="iso-8859-1"

0 commit comments

Comments
 (0)