@@ -1235,6 +1235,132 @@ hyperdb.py with::
12351235any call to convert an interval from raw form now has two simpler
12361236(and more friendly) ways to specify common time intervals.
12371237
1238+ Example: Modifying the mail gateway
1239+ -----------------------------------
1240+
1241+ One site receives email on a main gateway. The virtual alias delivery
1242+ table on the postfix server is configured with:
1243+
1244+ 1245+ 1246+ 1247+
1248+ These modifications to the mail gateway for roundup allows anonymous
1249+ submissions. It hides all of the requesters under the "support"
1250+ user. It also makes some other modifications to the mail parser
1251+ allowing keywords to be set and prefixes to be defined based on the
1252+ delivery alias.
1253+
1254+ This is the entry in interfaces.py::
1255+
1256+ import roundup.mailgw
1257+ import email.utils
1258+
1259+ class SupportTracker(object):
1260+ def __init__(self, prefix=None, keyword=None):
1261+ self.prefix = prefix
1262+ self.keyword = keyword
1263+
1264+ # Define new prefixes and keywords based on local address.
1265+ support_trackers = {
1266+ ### production instances ###
1267+
1268+ ### test instances ###
1269+ 'roundup-test+support-a':
1270+ SupportTracker(prefix='Support 1', keyword='support1'),
1271+ 'roundup-test+support-b':
1272+ SupportTracker(prefix='Support 2', keyword='support2'),
1273+ 'roundup-test2+support-a':
1274+ SupportTracker(prefix='Support 1', keyword='support1'),
1275+ 'roundup-test2+support-b':
1276+ SupportTracker(prefix='Support 2', keyword='support2'),
1277+ }
1278+
1279+ class parsedMessage(roundup.mailgw.parsedMessage):
1280+ def __init__(self, mailgw, message, support_tracker):
1281+ roundup.mailgw.parsedMessage.__init__(self, mailgw, message)
1282+ if support_tracker.prefix:
1283+ self.prefix = '%s: ' % support_tracker.prefix
1284+ else:
1285+ self.prefix = ''
1286+ self.keywords = []
1287+ if support_tracker.keyword:
1288+ try:
1289+ self.keywords = [
1290+ self.db.keyword.lookup(support_tracker.keyword)]
1291+ except KeyError:
1292+ pass
1293+ self.config.ADD_AUTHOR_TO_NOSY = 'no'
1294+ self.config.ADD_RECIPIENTS_TO_NOSY = 'no'
1295+ self.config.MAILGW_KEEP_QUOTED_TEXT = 'yes'
1296+ self.config.MAILGW_LEAVE_BODY_UNCHANGED = 'yes'
1297+ self.classname = 'issue'
1298+ self.pfxmode = 'loose'
1299+ self.sfxmode = 'none'
1300+ # set the support user id
1301+ self.fixed_author = self.db.user.lookup('support')
1302+ self.fixed_props = {
1303+ 'nosy': [self.fixed_author],
1304+ 'keyword': self.keywords,
1305+ }
1306+
1307+ def handle_help(self):
1308+ pass
1309+
1310+ def check_subject(self):
1311+ if not self.subject:
1312+ self.subject = 'no subject'
1313+
1314+ def rego_confirm(self):
1315+ pass
1316+
1317+ def get_author_id(self):
1318+ # force the support user to be the author
1319+ self.author = self.fixed_author
1320+
1321+ def get_props(self):
1322+ self.props = {}
1323+ if not self.nodeid:
1324+ self.props.update(self.fixed_props)
1325+ self.props['title'] = ("%s%s" % (
1326+ self.prefix, self.subject.replace('[', '(').replace(']', ')')))
1327+
1328+ def get_content_and_attachments(self):
1329+ roundup.mailgw.parsedMessage.get_content_and_attachments(self)
1330+ if not self.content:
1331+ self.content = 'no text'
1332+ intro = []
1333+ for header in ['From', 'To', 'Cc']:
1334+ for addr in self.message.getaddrlist(header):
1335+ intro.append('%s: %s' % (header, email.utils.formataddr(addr)))
1336+ intro.append('Subject: %s' % self.subject)
1337+ intro.append('\n')
1338+ self.content = '\n'.join(intro) + self.content
1339+
1340+ class MailGW(roundup.mailgw.MailGW):
1341+ def parsed_message_class(self, mailgw, message):
1342+ support_tracker = None
1343+ # The delivered-to header is unique to postfix
1344+ # it is the target address:
1345+ 1346+ # rather than
1347+ 1348+ recipients = message.getaddrlist('delivered-to')
1349+ if recipients:
1350+ localpart = recipients[0][1].rpartition('@')[0]
1351+ support_tracker = support_trackers.get(localpart)
1352+ if support_tracker:
1353+ # parse the mesage using the parsedMessage class
1354+ # defined above.
1355+ return parsedMessage(mailgw, message, support_tracker)
1356+ else:
1357+ # parse the message normally
1358+ return roundup.mailgw.parsedMessage(mailgw, message)
1359+
1360+ This is the most complex example section. The mail gateway is also one
1361+ of the more complex subsystems in roundup, and modifying it is not
1362+ trivial.
1363+
12381364Other Examples
12391365--------------
12401366
0 commit comments