Add option to create and set up RT ticket
authorAlex Dehnert <adehnert@mit.edu>
Mon, 18 Feb 2013 05:34:44 +0000 (00:34 -0500)
committerAlex Dehnert <adehnert@mit.edu>
Mon, 18 Feb 2013 05:34:44 +0000 (00:34 -0500)
If your organization uses RT, it may be helpful to mail-merge a message that
you send out through RT, and create corresponding RT tickets for each email.
We now support a --rt-queue option, allowing specifying a queue to create a
ticket in, and --rt-owner, to specify a owner (and AdminCC) for each created
ticket.

mail-merge

index 60bcefc3ed6c994be7c71821b0a371d1870c90c2..5a1e35b5ba53e062135fb3818e30b83d0f33787a 100755 (executable)
@@ -1,6 +1,8 @@
 #!/usr/bin/python
 
 import csv
+import email.parser
+from optparse import OptionParser
 import os
 import smtplib
 import subprocess
@@ -35,21 +37,78 @@ cmd_funcs = (lambda: True, sendmail_cmd)
 setup_sendmail, sendmail = smtp_funcs
 setup_sendmail, sendmail = cmd_funcs
 
-def mail_merge(cc_addr, email_file, recipients_file):
+def parse_arguments():
+    parser = OptionParser(usage='usage: %prog [options] cc_addr template recipients')
+    parser.add_option('-q', '--rt-queue', dest='rt_queue',
+            help='Automatically create a ticket in queue QUEUE',
+            metavar='QUEUE',
+    )
+    parser.add_option('-o', '--rt-owner', dest='rt_owner',
+            help='Set RT owner and AdminCC to USER',
+            metavar='USER',
+    )
+    (options, args) = parser.parse_args()
+    if len(args) != 3:
+        parser.error("incorrect number of arguments")
+    if options.rt_owner and not options.rt_queue:
+        parser.error("--rt-owner requires specifying a queue")
+    return options, args
+
+def msg_filter_factory(opts):
+    if not opts.rt_queue:
+        return lambda rcpt, body: body
+
+    import rtkit.tracker, rtkit.authenticators, rtkit.errors
+    cookie = rtkit.authenticators.CookieAuthenticator
+    resource = rtkit.resource.RTResource.from_rtrc(cookie)
+    parser = email.parser.Parser()
+
+    def filter_rt(rcpt, body, ):
+        msg = parser.parsestr(body)
+        content = {
+            'content': {
+                'Requestors': rcpt,
+                'Queue': opts.rt_queue,
+                'Subject' : msg['Subject'],
+                'Text' : '',
+            }
+        }
+        if opts.rt_owner:
+            content['content']['AdminCC'] = opts.rt_owner
+            content['content']['Owner'] = opts.rt_owner
+
+        try:
+            response = resource.post(path='ticket/new', payload=content,)
+            results = dict(response.parsed[0])
+            ticket, ticket_number = results['id'].split('/')
+            assert ticket == 'ticket', 'unexpected value "%s" instead of ticket' % (ticket, )
+            subject = "%s [help.mit.edu #%s]" % (msg['Subject'], ticket_number)
+            del msg['Subject']
+            msg['Subject'] = subject
+        except rtkit.errors.RTResourceError as e:
+            logger.error(e.response.status_int)
+            logger.error(e.response.status)
+            logger.error(e.response.parsed)
+
+        return msg.as_string()
+
+    return filter_rt
+
+def mail_merge(opts, cc_addr, email_file, recipients_file):
     email = open(email_file, 'r').read()
     reader = csv.reader(open(recipients_file, 'r'))
     header = reader.next()
+    msg_filter = msg_filter_factory(opts)
     print header
     for line in reader:
         dct = dictize_line(header, line, )
         print dct
         text = email % dct
+        text = msg_filter(dct['email'], text, )
+        print text
         sendmail([dct['email'], cc_addr, ], text, )
 
 if __name__=='__main__':
-    print "Syntax: $script $cc_addr $template $recipients"
+    options, args = parse_arguments()
     setup_sendmail()
-    cc_addr = sys.argv[1]
-    email_file = sys.argv[2]
-    recipients_file = sys.argv[3]
-    mail_merge(cc_addr, email_file, recipients_file, )
+    mail_merge(options, *args)