Guest User

Untitled

a guest
Jul 31st, 2018
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.02 KB | None | 0 0
  1. diff --git a/util/test/send_email.py b/util/test/send_email.py
  2. index 2447f6117b..1fc8c8d5d7 100755
  3. --- a/util/test/send_email.py
  4. +++ b/util/test/send_email.py
  5. @@ -1,7 +1,10 @@
  6. #!/usr/bin/env python
  7.  
  8. """Portable email sender. Acts as replacement for mail, Mail, mailx,
  9. -email (cygwin). Message body is taken from stdin.
  10. +email (cygwin). Message body is taken from stdin. Option to save the
  11. +message as a script file instead of immediately sending thru SMTP;
  12. +later, run that script file to send the same message, perhaps from
  13. +some other system.
  14. """
  15.  
  16. from __future__ import print_function
  17. @@ -14,6 +17,7 @@ import os
  18. import smtplib
  19. import socket
  20. import sys
  21. +import tempfile
  22.  
  23.  
  24. def main():
  25. @@ -23,7 +27,12 @@ def main():
  26. body = sys.stdin.read()
  27.  
  28. # Send the email!
  29. - send_email(args.recipients, body, args.subject, args.header, args.sender, args.smtp_host)
  30. + if not args.proxy_file:
  31. + # to SMTP server
  32. + send_email(args.recipients, body, args.subject, args.header, args.sender, args.smtp_host)
  33. + else:
  34. + # to save as a file
  35. + write_proxy_file(args, body)
  36.  
  37.  
  38. def send_email(recipients, body, subject=None, headers=None, sender=None, smtp_host=None):
  39. @@ -82,8 +91,9 @@ def _parse_headers(option, opt, value, parser, *args, **kwargs):
  40. # Split the value provided.
  41. parsed_vals = value.split(',')
  42. for v in parsed_vals:
  43. - key, value = v.split('=')
  44. - value_dict[key] = value
  45. + if '=' in v:
  46. + key, value = v.split('=')
  47. + value_dict[key] = value
  48.  
  49. # Set the updated dict to the oiption value.
  50. setattr(parser.values, option.dest, value_dict)
  51. @@ -100,6 +110,11 @@ def _default_smtp_host():
  52. """
  53. return os.environ.get('CHPL_UTIL_SMTP_HOST', 'localhost')
  54.  
  55. +def _default_proxy_file():
  56. + """Return path to proxy file if CHPL_UTIL_PROXY_FILE is set in environment.
  57. + """
  58. + return os.environ.get('CHPL_UTIL_PROXY_FILE', None )
  59. +
  60. def _parse_args():
  61. """Parse and return command line arguments."""
  62. class NoWrapHelpFormatter(optparse.IndentedHelpFormatter):
  63. @@ -120,32 +135,46 @@ def _parse_args():
  64. help='Verbose output.'
  65. )
  66.  
  67. - mail_group = optparse.OptionGroup(parser, 'Mail Options')
  68. + transport_group = optparse.OptionGroup(parser, 'Mail Transport Options')
  69. +
  70. + transport_group.add_option(
  71. + '--smtp-host',
  72. + default=_default_smtp_host(),
  73. + help='SMTP host to use when sending email.'
  74. + ' (default: %default ($CHPL_UTIL_SMTP_HOST, if defined; else "localhost"))'
  75. + )
  76. + transport_group.add_option(
  77. + '--proxy-file',
  78. + default=_default_proxy_file(),
  79. + help='Optional file path.'
  80. + ' If used, this e-mail message will not be sent to SMTP.'
  81. + ' Instead, a script to reproduce the message will be written to the "proxy file".'
  82. + ' (default: %default ($CHPL_UTIL_PROXY_FILE, if defined)'
  83. + )
  84. +
  85. + parser.add_option_group(transport_group)
  86.  
  87. - mail_group.add_option(
  88. + message_group = optparse.OptionGroup(parser, 'Message Options')
  89. +
  90. + message_group.add_option(
  91. '-s', '--subject',
  92. default=None,
  93. help='Email subject.'
  94. )
  95. - mail_group.add_option(
  96. + message_group.add_option(
  97. '-H', '--header',
  98. action='callback', type='string',
  99. callback=_parse_headers,
  100. help=('Email header(s) of form NAME=VALUE. '
  101. 'Specify more than one with comma delimited list.')
  102. )
  103. - mail_group.add_option(
  104. + message_group.add_option(
  105. '-S', '--sender',
  106. default=_default_sender(),
  107. help='Sender email address. (default: %default)'
  108. )
  109. - mail_group.add_option(
  110. - '--smtp-host',
  111. - default=_default_smtp_host(),
  112. - help='SMTP host to use when sending email. (default: %default)'
  113. - )
  114.  
  115. - parser.add_option_group(mail_group)
  116. + parser.add_option_group(message_group)
  117.  
  118. opts, args = parser.parse_args()
  119.  
  120. @@ -165,6 +194,98 @@ def _setup_logging(verbose=False):
  121. level=log_level)
  122. logging.debug('Verbose output enabled.')
  123.  
  124. +def write_proxy_file(args, body):
  125. + """Writes the optional "proxy file", a shell script able to recreate this
  126. +exact email message and send it later, even from a different machine.
  127. +This feature allows Chapel tests to run on slaves without an SNMP server.
  128. +"""
  129. +
  130. + # Example proxy file:
  131. + # send_email.py <<\EoF0 \
  132. + # -s 'My example e-mail notification' \
  133. + # -S sender-address@mail.com \
  134. + # -H Return-Path=return-address@mail.com, \
  135. + # address1@mail.com address2@mail.com
  136. + # The message body goes here.
  137. + # The end.
  138. + # EoF0
  139. +
  140. + try:
  141. + from shlex import quote # Python 3
  142. + except ImportError:
  143. + from pipes import quote # Python 2.6+
  144. +
  145. + # build send_email.py command script in string buffer
  146. +
  147. + for eofd in range(0, 1000):
  148. + if not "\nEoF%d\n" % (eofd) in "%s\n" % (body.rstrip()):
  149. + break
  150. +
  151. + command = "send_email.py <<\\EoF%d" % (eofd)
  152. + if args.subject:
  153. + command += " \\\n -s %s" % (quote(args.subject))
  154. + if args.sender:
  155. + command += " \\\n -S %s" % (quote(args.sender))
  156. + if args.header:
  157. + command += " \\\n -H "
  158. + headers = ""
  159. + for k,v in args.header.items():
  160. + headers += "%s=%s," % (k,v)
  161. + command += "%s" % (quote(headers))
  162. + if args.recipients:
  163. + command += " \\\n "
  164. + for v in args.recipients:
  165. + command += " %s" % (quote(v))
  166. +
  167. + command += "\n%s\nEoF%d" % (body.rstrip(),eofd)
  168. +
  169. + # prepare the proxy file for output, based on args.proxy_file, yet with uniqueness
  170. +
  171. + logging.debug('Ready --proxy-file=%s' % (args.proxy_file))
  172. +
  173. + dirname = os.path.dirname(args.proxy_file)
  174. + basename= os.path.basename(args.proxy_file)
  175. +
  176. + # mkdir a path to the given args.proxy_file, and ignore any exceptions
  177. +
  178. + try:
  179. + os.makedirs(os.path.dirname(args.proxy_file))
  180. + except:
  181. + pass
  182. +
  183. + # generate mktemp arguments based on the given args.proxy_file, or defaults
  184. + # we want mktemp to generate a unique filename like "send_email-XXXXX.sh"
  185. +
  186. + if basename:
  187. + if len(basename.rsplit('.', 1)) == 2:
  188. + (pref, suff) = basename.rsplit('.', 1)
  189. + if (not pref) and (not suff):
  190. + pref = 'send_email'
  191. + suff = '.'
  192. + elif not pref:
  193. + pref = '.' + suff
  194. + suff = ''
  195. + elif not suff:
  196. + suff = '.'
  197. + else:
  198. + pref = basename
  199. + suff = ''
  200. + else:
  201. + pref = 'send_email'
  202. + suff = '.sh'
  203. + if pref:
  204. + pref = pref.rstrip('-') + '-'
  205. + if suff:
  206. + suff = '.' + suff.lstrip('.')
  207. +
  208. + # open the file and write the string buffer into it
  209. +
  210. + (fd, pth) = tempfile.mkstemp(suffix=suff, prefix=pref, dir=dirname, text=True)
  211. + logging.info('Writing proxy file: %s' % (pth))
  212. + with os.fdopen(fd, 'w') as fp:
  213. + logging.debug('Command:\n%s' % (command))
  214. + fp.write("%s" % (command))
  215. +
  216.  
  217. if __name__ == '__main__':
  218. main()
Add Comment
Please, Sign In to add comment