--- Begin Message ---
- To: Debian Bug Tracking System <submit@bugs.debian.org>
- Subject: svnmailer: Should support multiple recipients with a single to_addr containing substitutions
- From: Raphael Hertzog <hertzog@debian.org>
- Date: Mon, 03 Mar 2008 18:22:24 +0100
- Message-id: <20080303172224.30163.2345.reportbug@localhost>
Package: svnmailer
Version: 1.0.8-8
Severity: wishlist
Hi,
when you use construct like those:
for_paths = (deb-maint|ext-maint|orphaned)/(?P<package>[^/]+)/
# Send to the PTS of the source package. Add any general commit list that
# you have for the project.
bcc_addr = %(package)s_cvs@packages.qa.debian.org
to_fake = %(package)s@packages.qa.debian.org
And when the commit spans multiple directories and thus matches multiple
values of <package>, it will only send one mail to one of the packages.
It should properly detect the list of packages and send to all intended
recipients.
Attached is an old patch where I was beginning to do this, it's advanced
enough to prove that it's doable but it still needs some checks from
someone more familiar with the code. I did send that patch to upstream
at the time I wrote it (April 2006) but it seems it never went further.
I was cleaning my harddrive and stumbled upon this patch and thus decided
to record it here in the BTS so that I can safely remove it from my disk
and still have some hope that the feature might one day be implemented.
:-)
Cheers,
-- System Information:
Debian Release: lenny/sid
APT prefers unstable
APT policy: (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: i386 (i686)
Kernel: Linux 2.6.24-1-686 (SMP w/1 CPU core)
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/bash
diff -ur svnmailer-1.0.8.old/src/lib/svnmailer/main.py svnmailer-1.0.8/src/lib/svnmailer/main.py
--- svnmailer-1.0.8.old/src/lib/svnmailer/main.py 2006-04-17 10:29:06.000000000 +0000
+++ svnmailer-1.0.8/src/lib/svnmailer/main.py 2006-04-22 12:37:42.000000000 +0000
@@ -256,6 +256,7 @@
# store the substdict for later use
for name, value in subst.items():
+ print "DEBUG: Store subdict: %s => %s" % (name, value)
group._sub_(name, value)
(selected_groups, ignored_groups)[
diff -ur svnmailer-1.0.8.old/src/lib/svnmailer/notifier/_mail.py svnmailer-1.0.8/src/lib/svnmailer/notifier/_mail.py
--- svnmailer-1.0.8.old/src/lib/svnmailer/notifier/_mail.py 2006-04-17 10:29:06.000000000 +0000
+++ svnmailer-1.0.8/src/lib/svnmailer/notifier/_mail.py 2006-04-22 13:08:57.000000000 +0000
@@ -254,7 +254,7 @@
from_addrs.extend(group.from_addr or [])
to_addrs.extend(group.to_addr or [])
bcc_addrs.extend(group.bcc_addr or [])
- to_fakes.extend(group.to_fake and [group.to_fake] or [])
+ to_fakes.extend(group.to_fake or [])
reply_to.extend(
group.reply_to_addr and [group.reply_to_addr] or []
)
diff -ur svnmailer-1.0.8.old/src/lib/svnmailer/settings.py svnmailer-1.0.8/src/lib/svnmailer/settings.py
--- svnmailer-1.0.8.old/src/lib/svnmailer/settings.py 2006-04-17 10:29:06.000000000 +0000
+++ svnmailer-1.0.8/src/lib/svnmailer/settings.py 2006-04-22 13:00:27.000000000 +0000
@@ -152,7 +152,7 @@
{'subst': True, 'map': True}),
'to_addr' : ('tokenlist',
{'subst': True, 'map': True}),
- 'to_fake' : ('unicode',
+ 'to_fake' : ('tokenlist',
{'subst': True, 'map': True}),
'bcc_addr' : ('tokenlist',
{'subst': True, 'map': True}),
diff -ur svnmailer-1.0.8.old/src/lib/svnmailer/struct_accessors.py svnmailer-1.0.8/src/lib/svnmailer/struct_accessors.py
--- svnmailer-1.0.8.old/src/lib/svnmailer/struct_accessors.py 2006-04-17 10:29:06.000000000 +0000
+++ svnmailer-1.0.8/src/lib/svnmailer/struct_accessors.py 2006-04-22 12:36:49.000000000 +0000
@@ -46,6 +46,7 @@
# global imports
from svnmailer import typedstruct, util
+import types
# Exceptions
@@ -421,7 +422,15 @@
def doSubstitute(self, value, subst, arg):
""" Substitutes the items """
- return tuple([util.substitute(token, subst) for token in value])
+ result = []
+ for token in value:
+ subst_token = util.substitute(token, subst)
+ if type(subst_token) == types.ListType:
+ print "DEBUG: Template generated several items"
+ result.extend(subst_token)
+ else:
+ result.append(subst_token)
+ return tuple(result)
def doPostmap(self, value, mapper, arg):
diff -ur svnmailer-1.0.8.old/src/lib/svnmailer/typedstruct.py svnmailer-1.0.8/src/lib/svnmailer/typedstruct.py
--- svnmailer-1.0.8.old/src/lib/svnmailer/typedstruct.py 2006-04-17 10:29:06.000000000 +0000
+++ svnmailer-1.0.8/src/lib/svnmailer/typedstruct.py 2006-04-22 12:41:42.000000000 +0000
@@ -84,6 +84,7 @@
# global imports
from svnmailer import util
+import types
class MemberDescriptor(object):
@@ -530,8 +531,18 @@
)
subst = self.private.getSubst(instance)
- if not default or not subst.has_key(name):
+ if not subst.has_key(name):
subst[name] = value
+ else:
+ # We keep all possible substitutions found
+ # Just ensure to not have duplicates
+ if type(subst[name]) is types.ListType:
+ if value not in subst[name]:
+ subst[name].append(value)
+ else:
+ if subst[name] != value:
+ newlist = [ subst[name], value ]
+ subst[name] = newlist
def getdict():
""" Returns the current dict (read-only) """
diff -ur svnmailer-1.0.8.old/src/lib/svnmailer/util.py svnmailer-1.0.8/src/lib/svnmailer/util.py
--- svnmailer-1.0.8.old/src/lib/svnmailer/util.py 2006-04-17 10:29:06.000000000 +0000
+++ svnmailer-1.0.8/src/lib/svnmailer/util.py 2006-04-22 13:14:47.000000000 +0000
@@ -44,7 +44,7 @@
]
# global imports
-import locale, os, sys
+import locale, os, sys, types
class TempFile(object):
@@ -420,8 +420,45 @@
if template is None:
return None
- return template % SafeDict(subst.items())
-
+ # Create the list of all substitutions to do
+ allsubst = [ {} ]
+ for name, value in subst.items():
+ if type(value) == types.ListType:
+ print "DEBUG: param %s is multiple" % name
+ # Take each existing subsitution and multiply them by the
+ # number of different values for the current parameter
+ newallsubst = []
+ for s in allsubst:
+ for v in value:
+ print "DEBUG: value %s" % v
+ newsubst = dict(s)
+ newsubst[name] = v
+ newallsubst.append(newsubst)
+ allsubst = newallsubst
+ else:
+ for s in allsubst:
+ s[name] = value
+
+ for s in allsubst:
+ print "DEBUG: Subst with:"
+ for n, v in s.items():
+ print "%s => %s" % (n, v)
+
+ result = [ template % SafeDict(s.items()) for s in allsubst ]
+
+ # Keep uniq values only
+ seen = {}
+ for r in result:
+ seen[r] = 1
+ result = seen.keys()
+
+ for r in result:
+ print "DEBUG: Substituted element: %s" % r
+
+ if len(result) == 1:
+ return result[0]
+ else:
+ return result
def filterForXml(value):
""" Replaces control characters with replace characters
--- End Message ---