PageRenderTime 51ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 1ms

/Src/Dependencies/Boost/tools/regression/xsl_reports/email_maintainers.py

http://hadesmem.googlecode.com/
Python | 840 lines | 714 code | 24 blank | 102 comment | 35 complexity | d9864f6c9185d7b2730cd6cec8a1bda9 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.0, Apache-2.0, LGPL-3.0
  1. #
  2. # Copyright (C) 2005, 2007 The Trustees of Indiana University
  3. # Author: Douglas Gregor
  4. #
  5. # Distributed under the Boost Software License, Version 1.0. (See
  6. # accompanying file LICENSE_1_0.txt or copy at
  7. # http://www.boost.org/LICENSE_1_0.txt)
  8. #
  9. import re
  10. import smtplib
  11. import os
  12. import time
  13. import string
  14. import datetime
  15. import sys
  16. report_author = "Douglas Gregor <dgregor@osl.iu.edu>"
  17. boost_dev_list = "Boost Developer List <boost@lists.boost.org>"
  18. boost_testing_list = "Boost Testing List <boost-testing@lists.boost.org>"
  19. def sorted_keys( dict ):
  20. result = dict.keys()
  21. result.sort()
  22. return result
  23. class Platform:
  24. """
  25. All of the failures for a particular platform.
  26. """
  27. def __init__(self, name):
  28. self.name = name
  29. self.failures = list()
  30. self.maintainers = list()
  31. return
  32. def addFailure(self, failure):
  33. self.failures.append(failure)
  34. return
  35. def isBroken(self):
  36. return len(self.failures) > 300
  37. def addMaintainer(self, maintainer):
  38. """
  39. Add a new maintainer for this platform.
  40. """
  41. self.maintainers.append(maintainer)
  42. return
  43. class Failure:
  44. """
  45. A single test case failure in the report.
  46. """
  47. def __init__(self, test, platform):
  48. self.test = test
  49. self.platform = platform
  50. return
  51. class Test:
  52. """
  53. All of the failures for a single test name within a library.
  54. """
  55. def __init__(self, library, name):
  56. self.library = library
  57. self.name = name
  58. self.failures = list()
  59. return
  60. def addFailure(self, failure):
  61. self.failures.append(failure)
  62. return
  63. def numFailures(self):
  64. return len(self.failures)
  65. def numReportableFailures(self):
  66. """
  67. Returns the number of failures that we will report to the
  68. maintainers of the library. This doesn't count failures on
  69. broken platforms.
  70. """
  71. count = 0
  72. for failure in self.failures:
  73. if not failure.platform.isBroken():
  74. count += 1
  75. pass
  76. pass
  77. return count
  78. class Library:
  79. """
  80. All of the information about the failures in a single library.
  81. """
  82. def __init__(self, name):
  83. self.name = name
  84. self.maintainers = list()
  85. self.tests = list()
  86. return
  87. def addTest(self, test):
  88. """
  89. Add another test to the library.
  90. """
  91. self.tests.append(test)
  92. return
  93. def addMaintainer(self, maintainer):
  94. """
  95. Add a new maintainer for this library.
  96. """
  97. self.maintainers.append(maintainer)
  98. return
  99. def numFailures(self):
  100. count = 0
  101. for test in self.tests:
  102. count += test.numFailures()
  103. pass
  104. return count
  105. def numReportableFailures(self):
  106. count = 0
  107. for test in self.tests:
  108. count += test.numReportableFailures()
  109. pass
  110. return count
  111. class Maintainer:
  112. """
  113. Information about the maintainer of a library
  114. """
  115. def __init__(self, name, email):
  116. self.name = name
  117. self.email = email
  118. self.libraries = list()
  119. return
  120. def addLibrary(self, library):
  121. self.libraries.append(library)
  122. return
  123. def composeEmail(self, report):
  124. """
  125. Composes an e-mail to this maintainer with information about
  126. the failures in his or her libraries, omitting those that come
  127. from "broken" platforms. Returns the e-mail text if a message
  128. needs to be sent, or None otherwise.
  129. """
  130. # Determine if we need to send a message to this developer.
  131. requires_message = False
  132. for library in self.libraries:
  133. if library.numReportableFailures() > 0:
  134. requires_message = True
  135. break
  136. if not requires_message:
  137. return None
  138. # Build the message header
  139. message = """From: Douglas Gregor <dgregor@osl.iu.edu>
  140. To: """
  141. message += self.name + ' <' + self.email + '>'
  142. message += """
  143. Reply-To: boost@lists.boost.org
  144. Subject: Failures in your Boost libraries as of """
  145. message += str(datetime.date.today()) + " [" + report.branch + "]"
  146. message += """
  147. You are receiving this report because one or more of the libraries you
  148. maintain has regression test failures that are not accounted for.
  149. A full version of the report is sent to the Boost developer's mailing
  150. list.
  151. Detailed report:
  152. """
  153. message += ' ' + report.url + """
  154. There are failures in these libraries you maintain:
  155. """
  156. # List the libraries this maintainer is responsible for and
  157. # the number of reportable failures in that library.
  158. for library in self.libraries:
  159. num_failures = library.numReportableFailures()
  160. if num_failures > 0:
  161. message += ' ' + library.name + ' (' + str(num_failures) + ')\n'
  162. pass
  163. pass
  164. # Provide the details for the failures in each library.
  165. for library in self.libraries:
  166. if library.numReportableFailures() > 0:
  167. message += '\n|' + library.name + '|\n'
  168. for test in library.tests:
  169. if test.numReportableFailures() > 0:
  170. message += ' ' + test.name + ':'
  171. for failure in test.failures:
  172. if not failure.platform.isBroken():
  173. message += ' ' + failure.platform.name
  174. pass
  175. pass
  176. message += '\n'
  177. pass
  178. pass
  179. pass
  180. pass
  181. return message
  182. class PlatformMaintainer:
  183. """
  184. Information about the platform maintainer of a library
  185. """
  186. def __init__(self, name, email):
  187. self.name = name
  188. self.email = email
  189. self.platforms = list()
  190. return
  191. def addPlatform(self, runner, platform):
  192. self.platforms.append(platform)
  193. return
  194. def composeEmail(self, report):
  195. """
  196. Composes an e-mail to this platform maintainer if one or more of
  197. the platforms s/he maintains has a large number of failures.
  198. Returns the e-mail text if a message needs to be sent, or None
  199. otherwise.
  200. """
  201. # Determine if we need to send a message to this developer.
  202. requires_message = False
  203. for platform in self.platforms:
  204. if platform.isBroken():
  205. requires_message = True
  206. break
  207. if not requires_message:
  208. return None
  209. # Build the message header
  210. message = """From: Douglas Gregor <dgregor@osl.iu.edu>
  211. To: """
  212. message += self.name + ' <' + self.email + '>'
  213. message += """
  214. Reply-To: boost@lists.boost.org
  215. Subject: Large number of Boost failures on a platform you maintain as of """
  216. message += str(datetime.date.today()) + " [" + report.branch + "]"
  217. message += """
  218. You are receiving this report because one or more of the testing
  219. platforms that you maintain has a large number of Boost failures that
  220. are not accounted for. A full version of the report is sent to the
  221. Boost developer's mailing list.
  222. Detailed report:
  223. """
  224. message += ' ' + report.url + """
  225. The following platforms have a large number of failures:
  226. """
  227. for platform in self.platforms:
  228. if platform.isBroken():
  229. message += (' ' + platform.name + ' ('
  230. + str(len(platform.failures)) + ' failures)\n')
  231. return message
  232. class Report:
  233. """
  234. The complete report of all failing test cases.
  235. """
  236. def __init__(self, branch = 'trunk'):
  237. self.branch = branch
  238. self.date = None
  239. self.url = None
  240. self.libraries = dict()
  241. self.platforms = dict()
  242. self.maintainers = dict()
  243. self.platform_maintainers = dict()
  244. return
  245. def getPlatform(self, name):
  246. """
  247. Retrieve the platform with the given name.
  248. """
  249. if self.platforms.has_key(name):
  250. return self.platforms[name]
  251. else:
  252. self.platforms[name] = Platform(name)
  253. return self.platforms[name]
  254. def getMaintainer(self, name, email):
  255. """
  256. Retrieve the maintainer with the given name and e-mail address.
  257. """
  258. if self.maintainers.has_key(name):
  259. return self.maintainers[name]
  260. else:
  261. self.maintainers[name] = Maintainer(name, email)
  262. return self.maintainers[name]
  263. def getPlatformMaintainer(self, name, email):
  264. """
  265. Retrieve the platform maintainer with the given name and
  266. e-mail address.
  267. """
  268. if self.platform_maintainers.has_key(name):
  269. return self.platform_maintainers[name]
  270. else:
  271. self.platform_maintainers[name] = PlatformMaintainer(name, email)
  272. return self.platform_maintainers[name]
  273. def parseIssuesEmail(self):
  274. """
  275. Try to parse the issues e-mail file. Returns True if everything was
  276. successful, false otherwise.
  277. """
  278. # See if we actually got the file
  279. if not os.path.isfile('issues-email.txt'):
  280. return False
  281. # Determine the set of libraries that have unresolved failures
  282. date_regex = re.compile('Report time: (.*)')
  283. url_regex = re.compile(' (http://.*)')
  284. library_regex = re.compile('\|(.*)\|')
  285. failure_regex = re.compile(' ([^:]*): (.*)')
  286. current_library = None
  287. for line in file('issues-email.txt', 'r'):
  288. # Check for the report time line
  289. m = date_regex.match(line)
  290. if m:
  291. self.date = m.group(1)
  292. continue
  293. # Check for the detailed report URL
  294. m = url_regex.match(line)
  295. if m:
  296. self.url = m.group(1)
  297. continue
  298. # Check for a library header
  299. m = library_regex.match(line)
  300. if m:
  301. current_library = Library(m.group(1))
  302. self.libraries[m.group(1)] = current_library
  303. continue
  304. # Check for a library test and its failures
  305. m = failure_regex.match(line)
  306. if m:
  307. test = Test(current_library, m.group(1))
  308. for platform_name in re.split('\s*', m.group(2)):
  309. if platform_name != '':
  310. platform = self.getPlatform(platform_name)
  311. failure = Failure(test, platform)
  312. test.addFailure(failure)
  313. platform.addFailure(failure)
  314. pass
  315. current_library.addTest(test)
  316. continue
  317. pass
  318. return True
  319. def getIssuesEmail(self):
  320. """
  321. Retrieve the issues email from beta.boost.org, trying a few
  322. times in case something wonky is happening. If we can retrieve
  323. the file, calls parseIssuesEmail and return True; otherwise,
  324. return False.
  325. """
  326. base_url = "http://beta.boost.org/development/tests/"
  327. base_url += self.branch
  328. base_url += "/developer/";
  329. got_issues = False
  330. # Ping the server by looking for an HTML file
  331. print "Pinging the server to initiate extraction..."
  332. ping_url = base_url + "issues.html"
  333. os.system('curl -O ' + ping_url)
  334. os.system('rm -f issues.html')
  335. for x in range(30):
  336. # Update issues-email.txt
  337. url = base_url + "issues-email.txt"
  338. print 'Retrieving issues email from ' + url
  339. os.system('rm -f issues-email.txt')
  340. os.system('curl -O ' + url)
  341. if self.parseIssuesEmail():
  342. return True
  343. print 'Failed to fetch issues email. '
  344. time.sleep (30)
  345. return False
  346. # Parses the file $BOOST_ROOT/libs/maintainers.txt to create a hash
  347. # mapping from the library name to the list of maintainers.
  348. def parseLibraryMaintainersFile(self):
  349. """
  350. Parse the maintainers file in ../../../libs/maintainers.txt to
  351. collect information about the maintainers of broken libraries.
  352. """
  353. lib_maintainer_regex = re.compile('(\S+)\s*(.*)')
  354. name_email_regex = re.compile('\s*(\w*(\s*\w+)+)\s*<\s*(\S*(\s*\S+)+)\S*>')
  355. at_regex = re.compile('\s*-\s*at\s*-\s*')
  356. for line in file('../../../libs/maintainers.txt', 'r'):
  357. if line.startswith('#'):
  358. continue
  359. m = lib_maintainer_regex.match (line)
  360. if m:
  361. libname = m.group(1)
  362. if self.libraries.has_key(m.group(1)):
  363. library = self.libraries[m.group(1)]
  364. for person in re.split('\s*,\s*', m.group(2)):
  365. nmm = name_email_regex.match(person)
  366. if nmm:
  367. name = nmm.group(1)
  368. email = nmm.group(3)
  369. email = at_regex.sub('@', email)
  370. maintainer = self.getMaintainer(name, email)
  371. maintainer.addLibrary(library)
  372. library.addMaintainer(maintainer)
  373. pass
  374. pass
  375. pass
  376. pass
  377. pass
  378. pass
  379. # Parses the file $BOOST_ROOT/libs/platform_maintainers.txt to
  380. # create a hash mapping from the platform name to the list of
  381. # maintainers.
  382. def parsePlatformMaintainersFile(self):
  383. """
  384. Parse the platform maintainers file in
  385. ../../../libs/platform_maintainers.txt to collect information
  386. about the maintainers of the various platforms.
  387. """
  388. platform_maintainer_regex = re.compile('([A-Za-z0-9_.-]*|"[^"]*")\s+(\S+)\s+(.*)')
  389. name_email_regex = re.compile('\s*(\w*(\s*\w+)+)\s*<\s*(\S*(\s*\S+)+)\S*>')
  390. at_regex = re.compile('\s*-\s*at\s*-\s*')
  391. for line in file('../../../libs/platform_maintainers.txt', 'r'):
  392. if line.startswith('#'):
  393. continue
  394. m = platform_maintainer_regex.match (line)
  395. if m:
  396. platformname = m.group(2)
  397. if self.platforms.has_key(platformname):
  398. platform = self.platforms[platformname]
  399. for person in re.split('\s*,\s*', m.group(3)):
  400. nmm = name_email_regex.match(person)
  401. if nmm:
  402. name = nmm.group(1)
  403. email = nmm.group(3)
  404. email = at_regex.sub('@', email)
  405. maintainer = self.getPlatformMaintainer(name, email)
  406. maintainer.addPlatform(m.group(1), platform)
  407. platform.addMaintainer(maintainer)
  408. pass
  409. pass
  410. pass
  411. pass
  412. pass
  413. def numFailures(self):
  414. count = 0
  415. for library in self.libraries:
  416. count += self.libraries[library].numFailures()
  417. pass
  418. return count
  419. def numReportableFailures(self):
  420. count = 0
  421. for library in self.libraries:
  422. count += self.libraries[library].numReportableFailures()
  423. pass
  424. return count
  425. def composeSummaryEmail(self):
  426. """
  427. Compose a message to send to the Boost developer's
  428. list. Return the message and return it.
  429. """
  430. message = """From: Douglas Gregor <dgregor@osl.iu.edu>
  431. To: boost@lists.boost.org
  432. Reply-To: boost@lists.boost.org
  433. Subject: [Report] """
  434. message += str(self.numFailures()) + " failures on " + branch
  435. if branch != 'trunk':
  436. message += ' branch'
  437. message += " (" + str(datetime.date.today()) + ")"
  438. message += """
  439. Boost regression test failures
  440. """
  441. message += "Report time: " + self.date + """
  442. This report lists all regression test failures on high-priority platforms.
  443. Detailed report:
  444. """
  445. message += ' ' + self.url + '\n\n'
  446. if self.numFailures() == 0:
  447. message += "No failures! Yay!\n"
  448. return message
  449. # List the platforms that are broken
  450. any_broken_platforms = self.numReportableFailures() < self.numFailures()
  451. if any_broken_platforms:
  452. message += """The following platforms have a large number of failures:
  453. """
  454. for platform in sorted_keys( self.platforms ):
  455. if self.platforms[platform].isBroken():
  456. message += (' ' + platform + ' ('
  457. + str(len(self.platforms[platform].failures))
  458. + ' failures)\n')
  459. message += """
  460. Failures on these "broken" platforms will be omitted from the results below.
  461. Please see the full report for information about these failures.
  462. """
  463. # Display the number of failures
  464. message += (str(self.numReportableFailures()) + ' failures in ' +
  465. str(len(self.libraries)) + ' libraries')
  466. if any_broken_platforms:
  467. message += (' (plus ' + str(self.numFailures() - self.numReportableFailures())
  468. + ' from broken platforms)')
  469. message += '\n'
  470. # Display the number of failures per library
  471. for k in sorted_keys( self.libraries ):
  472. library = self.libraries[k]
  473. num_failures = library.numFailures()
  474. message += ' ' + library.name + ' ('
  475. if library.numReportableFailures() > 0:
  476. message += (str(library.numReportableFailures())
  477. + " failures")
  478. if library.numReportableFailures() < num_failures:
  479. if library.numReportableFailures() > 0:
  480. message += ', plus '
  481. message += (str(num_failures-library.numReportableFailures())
  482. + ' failures on broken platforms')
  483. message += ')\n'
  484. pass
  485. message += '\n'
  486. # Provide the details for the failures in each library.
  487. for k in sorted_keys( self.libraries ):
  488. library = self.libraries[k]
  489. if library.numReportableFailures() > 0:
  490. message += '\n|' + library.name + '|\n'
  491. for test in library.tests:
  492. if test.numReportableFailures() > 0:
  493. message += ' ' + test.name + ':'
  494. for failure in test.failures:
  495. platform = failure.platform
  496. if not platform.isBroken():
  497. message += ' ' + platform.name
  498. message += '\n'
  499. return message
  500. def composeTestingSummaryEmail(self):
  501. """
  502. Compose a message to send to the Boost Testing list. Returns
  503. the message text if a message is needed, returns None
  504. otherwise.
  505. """
  506. brokenPlatforms = 0
  507. for platform in sorted_keys( self.platforms ):
  508. if self.platforms[platform].isBroken():
  509. brokenPlatforms = brokenPlatforms + 1
  510. if brokenPlatforms == 0:
  511. return None;
  512. message = """From: Douglas Gregor <dgregor@osl.iu.edu>
  513. To: boost-testing@lists.boost.org
  514. Reply-To: boost-testing@lists.boost.org
  515. Subject: [Report] """
  516. message += str(brokenPlatforms) + " potentially broken platforms on " + branch
  517. if branch != 'trunk':
  518. message += ' branch'
  519. message += " (" + str(datetime.date.today()) + ")"
  520. message += """
  521. Potentially broken platforms for Boost regression testing
  522. """
  523. message += "Report time: " + self.date + """
  524. This report lists the high-priority platforms that are exhibiting a
  525. large number of regression test failures, which might indicate a problem
  526. with the test machines or testing harness.
  527. Detailed report:
  528. """
  529. message += ' ' + self.url + '\n'
  530. message += """
  531. Platforms with a large number of failures:
  532. """
  533. for platform in sorted_keys( self.platforms ):
  534. if self.platforms[platform].isBroken():
  535. message += (' ' + platform + ' ('
  536. + str(len(self.platforms[platform].failures))
  537. + ' failures)\n')
  538. return message
  539. # Send a message to "person" (a maintainer of a library that is
  540. # failing).
  541. # maintainers is the result of get_library_maintainers()
  542. def send_individualized_message (branch, person, maintainers):
  543. # There are several states we could be in:
  544. # 0 Initial state. Eat everything up to the "NNN failures in MMM
  545. # libraries" line
  546. # 1 Suppress output within this library
  547. # 2 Forward output within this library
  548. state = 0
  549. failures_in_lib_regex = re.compile('\d+ failur.*\d+ librar')
  550. lib_failures_regex = re.compile(' (\S+) \((\d+)\)')
  551. lib_start_regex = re.compile('\|(\S+)\|')
  552. general_pass_regex = re.compile(' http://')
  553. for line in file('issues-email.txt', 'r'):
  554. if state == 0:
  555. lfm = lib_failures_regex.match(line)
  556. if lfm:
  557. # Pass the line through if the current person is a
  558. # maintainer of this library
  559. if lfm.group(1) in maintainers and person in maintainers[lfm.group(1)]:
  560. message += line
  561. print line,
  562. elif failures_in_lib_regex.match(line):
  563. message += "\nThere are failures in these libraries you maintain:\n"
  564. elif general_pass_regex.match(line):
  565. message += line
  566. lib_start = lib_start_regex.match(line)
  567. if lib_start:
  568. if state == 0:
  569. message += '\n'
  570. if lib_start.group(1) in maintainers and person in maintainers[lib_start.group(1)]:
  571. message += line
  572. state = 2
  573. else:
  574. state = 1
  575. else:
  576. if state == 1:
  577. pass
  578. elif state == 2:
  579. message += line
  580. if '--debug' in sys.argv:
  581. print '-----------------Message text----------------'
  582. print message
  583. else:
  584. print
  585. if '--send' in sys.argv:
  586. print "Sending..."
  587. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  588. smtp.sendmail(from_addr = 'Douglas Gregor <dgregor@osl.iu.edu>',
  589. to_addrs = person[1],
  590. msg = message)
  591. print "Done."
  592. # Send a message to the developer's list
  593. def send_boost_developers_message(branch, maintainers, failing_libraries):
  594. to_line = 'boost@lists.boost.org'
  595. from_line = 'Douglas Gregor <dgregor@osl.iu.edu>'
  596. message = """From: Douglas Gregor <dgregor@osl.iu.edu>
  597. To: boost@lists.boost.org
  598. Reply-To: boost@lists.boost.org
  599. Subject: Boost regression testing notification ("""
  600. message += str(datetime.date.today()) + " [" + branch + "]"
  601. message += ")"
  602. message += """
  603. """
  604. for line in file('issues-email.txt', 'r'):
  605. # Right before the detailed report, put out a warning message if
  606. # any libraries with failures to not have maintainers listed.
  607. if line.startswith('Detailed report:'):
  608. missing_maintainers = False
  609. for lib in failing_libraries:
  610. if not(lib in maintainers) or maintainers[lib] == list():
  611. missing_maintainers = True
  612. if missing_maintainers:
  613. message += """WARNING: The following libraries have failing regression tests but do
  614. not have a maintainer on file. Once a maintainer is found, add an
  615. entry to libs/maintainers.txt to eliminate this message.
  616. """
  617. for lib in failing_libraries:
  618. if not(lib in maintainers) or maintainers[lib] == list():
  619. message += ' ' + lib + '\n'
  620. message += '\n'
  621. message += line
  622. if '--send' in sys.argv:
  623. print 'Sending notification email...'
  624. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  625. smtp.sendmail(from_addr = from_line, to_addrs = to_line, msg = message)
  626. print 'Done.'
  627. if '--debug' in sys.argv:
  628. print "----------Boost developer's message text----------"
  629. print message
  630. ###############################################################################
  631. # Main program #
  632. ###############################################################################
  633. # Parse command-line options
  634. branch = "trunk"
  635. for arg in sys.argv:
  636. if arg.startswith("--branch="):
  637. branch = arg[len("--branch="):]
  638. report = Report(branch)
  639. # Try to parse the issues e-mail
  640. if '--no-get' in sys.argv:
  641. okay = report.parseIssuesEmail()
  642. else:
  643. okay = report.getIssuesEmail()
  644. if not okay:
  645. print 'Aborting.'
  646. if '--send' in sys.argv:
  647. message = """From: Douglas Gregor <dgregor@osl.iu.edu>
  648. To: Douglas Gregor <dgregor@osl.iu.edu>
  649. Reply-To: boost@lists.boost.org
  650. Subject: Regression status script failed on """
  651. message += str(datetime.date.today()) + " [" + branch + "]"
  652. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  653. smtp.sendmail(from_addr = 'Douglas Gregor <dgregor@osl.iu.edu>',
  654. to_addrs = 'dgregor@osl.iu.edu',
  655. msg = message)
  656. sys.exit(1)
  657. # Try to parse maintainers information
  658. report.parseLibraryMaintainersFile()
  659. report.parsePlatformMaintainersFile()
  660. # Generate individualized e-mail for library maintainers
  661. for maintainer_name in report.maintainers:
  662. maintainer = report.maintainers[maintainer_name]
  663. email = maintainer.composeEmail(report)
  664. if email:
  665. if '--send' in sys.argv:
  666. print ('Sending notification email to ' + maintainer.name + '...')
  667. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  668. smtp.sendmail(from_addr = report_author,
  669. to_addrs = maintainer.email,
  670. msg = email)
  671. print 'done.\n'
  672. else:
  673. print 'Would send a notification e-mail to',maintainer.name
  674. if '--debug' in sys.argv:
  675. print ('Message text for ' + maintainer.name + ':\n')
  676. print email
  677. # Generate individualized e-mail for platform maintainers
  678. for maintainer_name in report.platform_maintainers:
  679. maintainer = report.platform_maintainers[maintainer_name]
  680. email = maintainer.composeEmail(report)
  681. if email:
  682. if '--send' in sys.argv:
  683. print ('Sending notification email to ' + maintainer.name + '...')
  684. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  685. smtp.sendmail(from_addr = report_author,
  686. to_addrs = maintainer.email,
  687. msg = email)
  688. print 'done.\n'
  689. else:
  690. print 'Would send a notification e-mail to',maintainer.name
  691. if '--debug' in sys.argv:
  692. print ('Message text for ' + maintainer.name + ':\n')
  693. print email
  694. email = report.composeSummaryEmail()
  695. if '--send' in sys.argv:
  696. print 'Sending summary email to Boost developer list...'
  697. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  698. smtp.sendmail(from_addr = report_author,
  699. to_addrs = boost_dev_list,
  700. msg = email)
  701. print 'done.\n'
  702. if '--debug' in sys.argv:
  703. print 'Message text for summary:\n'
  704. print email
  705. email = report.composeTestingSummaryEmail()
  706. if email:
  707. if '--send' in sys.argv:
  708. print 'Sending summary email to Boost testing list...'
  709. smtp = smtplib.SMTP('milliways.osl.iu.edu')
  710. smtp.sendmail(from_addr = report_author,
  711. to_addrs = boost_testing_list,
  712. msg = email)
  713. print 'done.\n'
  714. if '--debug' in sys.argv:
  715. print 'Message text for testing summary:\n'
  716. print email
  717. if not ('--send' in sys.argv):
  718. print 'Chickening out and not sending any e-mail.'
  719. print 'Use --send to actually send e-mail, --debug to see e-mails.'