bbarchivist.smtputils.smtp_config_generator()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 7
nop 1
dl 0
loc 13
ccs 7
cts 7
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
#!/usr/bin/env python3
2 5
"""This module is used for dealing with SMTP email sending."""
3
4 5
import getpass  # passwords
5 5
import smtplib  # smtp connection
6 5
from email.mime.text import MIMEText  # email formatting
7
8 5
from bbarchivist import iniconfig  # config parsing
9 5
from bbarchivist import utilities  # file work
10
11 5
__author__ = "Thurask"
12 5
__license__ = "WTFPL v2"
13 5
__copyright__ = "2015-2019 Thurask"
14
15
16 5
def smtp_config_loader(homepath=None):
17
    """
18
    Read a ConfigParser file to get email preferences.
19
20
    :param homepath: Folder containing ini file. Default is user directory.
21
    :type homepath: str
22
    """
23 5
    resultdict = {}
24 5
    smtpini = iniconfig.generic_loader("email", homepath)
25 5
    resultdict['server'] = smtpini.get('server', fallback=None)
26 5
    resultdict['port'] = int(smtpini.getint('port', fallback=0))
27 5
    resultdict['username'] = smtpini.get('username', fallback=None)
28 5
    resultdict['password'] = smtpini.get('password', fallback=None)
29 5
    resultdict['is_ssl'] = smtpini.get('is_ssl', fallback=None)
30 5
    return resultdict
31
32
33 5
def smtp_config_writer_kwargs(kwargs, config, key):
34
    """
35
    Set server/port/username/password config.
36
37
    :param kwargs: Values. Refer to `:func:smtp_config_writer`.
38
    :type kwargs: dict
39
40
    :param config: Configuration dictionary.
41
    :type config: dict
42
43
    :param key: Key for kwargs and config dict.
44
    :type key: str
45
    """
46 5
    if kwargs[key] is not None:
47 5
        config[key] = kwargs[key]
48 5
    return kwargs
49
50
51 5
def smtp_config_writer_ssl(kwargs, config):
52
    """
53
    Set SSL/TLS config.
54
55
    :param kwargs: Values. Refer to `:func:smtp_config_writer`.
56
    :type kwargs: dict
57
58
    :param config: Configuration dictionary.
59
    :type config: dict
60
    """
61 5
    if kwargs['is_ssl'] is not None:
62 5
        config['is_ssl'] = str(kwargs['is_ssl']).lower()
63 5
    return config
64
65
66 5
def smtp_config_writer(**kwargs):
67
    """
68
    Write a ConfigParser file to store email server details.
69
70
    :param server: SMTP email server.
71
    :type server: str
72
73
    :param port: Port to use.
74
    :type port: int
75
76
    :param username: Email address.
77
    :type username: str
78
79
    :param password: Email password, optional.
80
    :type password: str
81
82
    :param is_ssl: True if server uses SSL, False if TLS only.
83
    :type is_ssl: bool
84
85
    :param homepath: Folder containing ini file. Default is user directory.
86
    :type homepath: str
87
    """
88 5
    results = {}
89 5
    results = smtp_config_writer_kwargs(kwargs, results, "server")
90 5
    results = smtp_config_writer_kwargs(kwargs, results, "port")
91 5
    results = smtp_config_writer_kwargs(kwargs, results, "username")
92 5
    results = smtp_config_writer_kwargs(kwargs, results, "password")
93 5
    results = smtp_config_writer_ssl(kwargs, results)
94 5
    iniconfig.generic_writer("email", results, kwargs['homepath'])
95
96
97 5
def smtp_config_generator_str(results, key, inp):
98
    """
99
    Set server/username config.
100
101
    :param kwargs: Values. Refer to `:func:smtp_config_writer`.
102
    :type kwargs: dict
103
104
    :param key: Key for results dict.
105
    :type key: str
106
107
    :param inp: Input question.
108
    :type inp: str
109
    """
110 5
    if results[key] is None:
111 5
        results[key] = input(inp)
112 5
    return results
113
114
115 5
def smtp_config_generator_port(results):
116
    """
117
    Generate port config.
118
119
    :param results: Values. Refer to `:func:smtp_config_writer`.
120
    :type results: dict
121
    """
122 5
    if results['port'] == 0:
123 5
        results['port'] = input("SMTP SERVER PORT: ")
124 5
    return results
125
126
127 5
def smtp_config_generator_password(results):
128
    """
129
    Generate password config.
130
131
    :param results: Values. Refer to `:func:smtp_config_writer`.
132
    :type results: dict
133
    """
134 5
    if results['password'] is None:
135 5
        results['password'] = getpass.getpass(prompt="PASSWORD: ")
136 5
    return results
137
138
139 5
def smtp_config_generator_ssl(results):
140
    """
141
    Generate SSL/TLS config.
142
143
    :param results: Values. Refer to `:func:smtp_config_writer`.
144
    :type results: dict
145
    """
146 5
    if results['is_ssl'] is None:
147 5
        use_ssl = utilities.i2b("Y: SSL, N: TLS (Y/N): ")
148 5
        results['is_ssl'] = "true" if use_ssl else "false"
149 5
    return results
150
151
152 5
def smtp_config_generator(results):
153
    """
154
    Take user input to create the SMTP config settings.
155
156
    :param results: The results to put in bbarchivist.ini.
157
    :type results: dict
158
    """
159 5
    results = smtp_config_generator_str(results, "server", "SMTP SERVER ADDRESS: ")
160 5
    results = smtp_config_generator_port(results)
161 5
    results = smtp_config_generator_str(results, "username", "EMAIL ADDRESS: ")
162 5
    results = smtp_config_generator_password(results)
163 5
    results = smtp_config_generator_ssl(results)
164 5
    return results
165
166
167 5
def send_email(kwargs):
168
    """
169
    Wrap email sending based on SSL/TLS.
170
171
    :param server: SMTP email server.
172
    :type server: str
173
174
    :param port: Port to use.
175
    :type port: int
176
177
    :param username: Email address.
178
    :type username: str
179
180
    :param password: Email password, optional.
181
    :type password: str
182
183
    :param is_ssl: True if server uses SSL, False if TLS only.
184
    :type is_ssl: bool
185
186
    :param software: Software release.
187
    :type software: str
188
189
    :param os: OS version.
190
    :type os: str
191
192
    :param body: Email message body.
193
    :type body: str
194
    """
195 5
    password = smtp_config_generator_password(kwargs)
196 5
    server, username, port, password = parse_kwargs(kwargs)
197 5
    subject = generate_subject(kwargs['software'], kwargs['os'])
198 5
    message = generate_message(kwargs['body'], username, subject)
199 5
    payload = {
200
        "server": server,
201
        "port": port,
202
        "username": username,
203
        "password": password,
204
        "message": message,
205
        "is_ssl": utilities.s2b(kwargs["is_ssl"])
206
    }
207 5
    send_email_post(payload)
208
209
210 5
def prep_smtp_instance(kwargs):
211
    """
212
    Prepare a smtplib.SMTP/SMTP_SSL instance.
213
214
    :param is_ssl: True if server uses SSL, False if TLS only.
215
    :type is_ssl: bool
216
217
    :param server: SMTP email server.
218
    :type server: str
219
220
    :param port: Port to use.
221
    :type port: int
222
    """
223 5
    args = kwargs['server'], kwargs['port']
224 5
    smt = smtplib.SMTP_SSL(*args) if kwargs['is_ssl'] else smtplib.SMTP(*args)
225 5
    return smt
226
227
228 5
def send_email_post(kwargs):
229
    """
230
    Send email through SSL/TLS.
231
232
    :param server: SMTP email server.
233
    :type server: str
234
235
    :param port: Port to use.
236
    :type port: int
237
238
    :param username: Email address.
239
    :type username: str
240
241
    :param password: Email password.
242
    :type password: str
243
244
    :param message: Message to send, with body and subject.
245
    :type message: MIMEText
246
    """
247 5
    smt = prep_smtp_instance(kwargs)
248 5
    smt.ehlo()
249 5
    if not kwargs['is_ssl']:
250 5
        smt.starttls()
251 5
    smt.login(kwargs['username'], kwargs['password'])
252 5
    smt.sendmail(kwargs['username'], kwargs['username'], kwargs['message'].as_string())
253 5
    smt.quit()
254
255
256 5
def parse_kwargs(kwargs):
257
    """
258
    Extract variables from kwargs.
259
260
    :param server: SMTP email server.
261
    :type server: str
262
263
    :param port: Port to use.
264
    :type port: int
265
266
    :param username: Email address.
267
    :type username: str
268
269
    :param password: Email password, optional.
270
    :type password: str
271
    """
272 5
    server = kwargs['server']
273 5
    username = kwargs['username']
274 5
    port = kwargs['port']
275 5
    password = kwargs['password']
276 5
    return server, username, port, password
277
278
279 5
def generate_message(body, username, subject):
280
    """
281
    Generate message body/headers.
282
283
    :param body: Body of text.
284
    :type body: str
285
286
    :param username: Address to send to and from.
287
    :type username: str
288
289
    :param subject: Subject of message.
290
    :type subject: str
291
    """
292 5
    msg = MIMEText(body)
293 5
    msg['Subject'] = subject
294 5
    msg['From'] = username
295 5
    msg['To'] = username
296 5
    return msg
297
298
299 5
def generate_subject(softwarerelease, osversion):
300
    """
301
    Generate message subject.
302
303
    :param softwarerelease: Software version.
304
    :type softwarerelease: str
305
306
    :param osversion: OS version.
307
    :type osversion: str
308
    """
309 5
    return "SW {0} - OS {1} available!".format(softwarerelease, osversion)
310
311
312 5
def prep_email(osversion, softwarerelease, password=None):
313
    """
314
    Bootstrap the whole process.
315
316
    :param osversion: OS version.
317
    :type osversion: str
318
319
    :param softwarerelease: Software version.
320
    :type softwarerelease: str
321
322
    :param password: Email password. None to prompt later.
323
    :type password: str
324
    """
325 5
    results = smtp_config_loader()
326 5
    results['homepath'] = None
327 5
    smtp_config_writer(**results)
328 5
    results['software'] = softwarerelease
329 5
    results['os'] = osversion
330 5
    results['body'] = utilities.return_and_delete("TEMPFILE.txt")
331 5
    if password is not None:
332 5
        results['password'] = password
333
    send_email(results)
334