source: rtems-tools/rtemstoolkit/mailer.py @ 9277878

5
Last change on this file since 9277878 was 9277878, checked in by Joel Sherrill <joel@…>, on 02/21/19 at 23:52:49

rtemstoolkit/mailer.py: Check for no --smtp-host arg being provided

  • Property mode set to 100644
File size: 6.0 KB
RevLine 
[50fdf12]1#
2# RTEMS Tools Project (http://www.rtems.org/)
[b0fa2ae]3# Copyright 2013-2016 Chris Johns (chrisj@rtems.org)
[50fdf12]4# All rights reserved.
5#
6# This file is part of the RTEMS Tools package in 'rtems-tools'.
7#
8# Redistribution and use in source and binary forms, with or without
9# modification, are permitted provided that the following conditions are met:
10#
11# 1. Redistributions of source code must retain the above copyright notice,
12# this list of conditions and the following disclaimer.
13#
14# 2. Redistributions in binary form must reproduce the above copyright notice,
15# this list of conditions and the following disclaimer in the documentation
16# and/or other materials provided with the distribution.
17#
18# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28# POSSIBILITY OF SUCH DAMAGE.
29#
30
31#
32# Manage emailing results or reports.
33#
34
[b0fa2ae]35from __future__ import print_function
36
[50fdf12]37import os
38import smtplib
39import socket
40
[7e5cdea]41from rtemstoolkit import error
42from rtemstoolkit import options
43from rtemstoolkit import path
[50fdf12]44
[7051ba5]45_options = {
46    '--mail'     : 'Send email report or results.',
47    '--smtp-host': 'SMTP host to send via.',
48    '--mail-to'  : 'Email address to send the email too.',
49    '--mail-from': 'Email address the report is from.'
50}
51
[50fdf12]52def append_options(opts):
[7051ba5]53    for o in _options:
54        opts[o] = _options[o]
55
56def add_arguments(argsp):
57    argsp.add_argument('--mail', help = _options['--mail'], action = 'store_true')
58    for o in ['--smtp-host', '--mail-to', '--mail-from']:
59        argsp.add_argument(o, help = _options[o], type = str)
[50fdf12]60
61class mail:
62    def __init__(self, opts):
63        self.opts = opts
64
[7051ba5]65    def _args_are_macros(self):
[571db94]66        return isinstance(self.opts, options.command_line)
[7051ba5]67
68    def _get_arg(self, arg):
69        if self._args_are_macros():
[9277878]70            value = self.opts.find_arg(arg)
71            if value is not None:
72                value = self.opts.find_arg(arg)[1]
[7051ba5]73        else:
74            if arg.startswith('--'):
75                arg = arg[2:]
76            arg = arg.replace('-', '_')
77            if arg in vars(self.opts):
78                value = vars(self.opts)[arg]
79            else:
80                value = None
81        return value
82
[50fdf12]83    def from_address(self):
84
85        def _clean(l):
86            if '#' in l:
87                l = l[:l.index('#')]
88            if '\r' in l:
89                l = l[:l.index('r')]
90            if '\n' in l:
91                l = l[:l.index('\n')]
92            return l.strip()
93
[7051ba5]94        addr = self._get_arg('--mail-from')
[50fdf12]95        if addr is not None:
[7051ba5]96            return addr
[50fdf12]97        mailrc = None
98        if 'MAILRC' in os.environ:
99            mailrc = os.environ['MAILRC']
100        if mailrc is None and 'HOME' in os.environ:
101            mailrc = path.join(os.environ['HOME'], '.mailrc')
102        if mailrc is not None and path.exists(mailrc):
103            # set from="Joe Blow <joe@blow.org>"
104            try:
[dc5de5f]105                with open(mailrc, 'r') as mrc:
106                    lines = mrc.readlines()
[04a5204]107            except IOError as err:
[50fdf12]108                raise error.general('error reading: %s' % (mailrc))
109            for l in lines:
110                l = _clean(l)
111                if 'from' in l:
112                    fa = l[l.index('from') + len('from'):]
113                    if '=' in fa:
114                        addr = fa[fa.index('=') + 1:].replace('"', ' ').strip()
115            if addr is not None:
116                return addr
[7051ba5]117        if self._args_are_macros():
118            addr = self.opts.defaults.get_value('%{_sbgit_mail}')
119        else:
120            raise error.general('no valid from address for mail')
[50fdf12]121        return addr
122
123    def smtp_host(self):
[7051ba5]124        host = self._get_arg('--smtp-host')
[50fdf12]125        if host is not None:
126            return host[1]
[7051ba5]127        if self._args_are_macros():
128            host = self.opts.defaults.get_value('%{_mail_smtp_host}')
[50fdf12]129        if host is not None:
130            return host
131        return 'localhost'
132
133    def send(self, to_addr, subject, body):
134        from_addr = self.from_address()
135        msg = "From: %s\r\nTo: %s\r\nSubject: %s\r\n\r\n" % \
136            (from_addr, to_addr, subject) + body
137        try:
138            s = smtplib.SMTP(self.smtp_host())
139            s.sendmail(from_addr, [to_addr], msg)
[04a5204]140        except smtplib.SMTPException as se:
[50fdf12]141            raise error.general('sending mail: %s' % (str(se)))
[04a5204]142        except socket.error as se:
[50fdf12]143            raise error.general('sending mail: %s' % (str(se)))
144
[dc5de5f]145    def send_file_as_body(self, to_addr, subject, name, intro = None):
146        try:
147            with open(name, 'r') as f:
148                body = f.readlines()
149        except IOError as err:
150            raise error.general('error reading mail body: %s' % (name))
151        if intro is not None:
152            body = intro + body
153        self.send(to_addr, from_addr, body)
154
[50fdf12]155if __name__ == '__main__':
156    import sys
[7e5cdea]157    from rtemstoolkit import macros
[50fdf12]158    optargs = {}
[7e5cdea]159    rtdir = 'rtemstoolkit'
160    defaults = '%s/defaults.mc' % (rtdir)
[50fdf12]161    append_options(optargs)
[7e5cdea]162    opts = options.command_line(base_path = '.',
163                                argv = sys.argv,
164                                optargs = optargs,
165                                defaults = macros.macros(name = defaults, rtdir = rtdir),
166                                command_path = '.')
167    options.load(opts)
[50fdf12]168    m = mail(opts)
[04a5204]169    print('From: %s' % (m.from_address()))
170    print('SMTP Host: %s' % (m.smtp_host()))
[7e5cdea]171    if '--mail' in sys.argv:
172        m.send(m.from_address(), 'Test mailer.py', 'This is a test')
Note: See TracBrowser for help on using the repository browser.