/
file.py
107 lines (87 loc) · 3.12 KB
/
file.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
# -*- coding: utf-8 -*-
u"""
A diagnostic utility that can be used to render email messages to files on disk.
"""
from __future__ import absolute_import, division, print_function
import errno
import logging
import os
from datetime import datetime
import attr
import six
from edx_ace.channel import Channel, ChannelType
LOG = logging.getLogger(__name__)
PATH_OVERRIDE_KEY = u'output_file_path'
DEFAULT_OUTPUT_FILE_PATH_TPL = u'/edx/src/ace_messages/{recipient.username}.{date:%Y%m%d-%H%M%S}.html'
TEMPLATE = u"""
<!DOCTYPE html>
<html>
<head>
{head_html}
</head>
<body>
{body_html}
</body>
<!-- to: {email_address} -->
<!-- from_name: {from_name} -->
<!-- subject: {subject} -->
<!-- body: {body} -->
</html>
"""
STDOUT_TEMPLATE = u"""
------- EMAIL -------
To: {email_address}
From: {from_name}
Subject: {subject}
Body:
{body}
------- END -------
"""
OUTPUT_ENCODING = u'utf8'
class FileEmailChannel(Channel):
u"""
An email channel that simply renders the message HTML to a file and the body text to stdout.
If you add this channel to your enabled channels list as your email channel, it will write out the text version
of the email to stdout and the HTML version to an output file.
Examples::
ACE_ENABLED_CHANNELS = ['file_email']
By default it writes the output file to /edx/src/ace_output.html and overwrites any existing file at that location.
In the edX devstack, this folder is shared between the host and the containers so you can easily open the file using
a browser on the host. You can override this output file location by passing in a ``output_file_path`` key in the
message options. That path specifies where in the container filesystem the file should be written.
Both streams of output are UTF-8 encoded.
"""
channel_type = ChannelType.EMAIL
@classmethod
def enabled(cls):
u"""
Returns: True always!
"""
return True
def _encode(self, s): # pragma: no cover
if six.PY2:
return s.encode(OUTPUT_ENCODING)
else:
return s
def deliver(self, message, rendered_message):
template_vars = {k: v.strip() for k, v in attr.asdict(rendered_message).items()}
template_vars[u'email_address'] = message.recipient.email_address
rendered_template = TEMPLATE.format(**template_vars)
output_file_path = message.options.get(PATH_OVERRIDE_KEY, DEFAULT_OUTPUT_FILE_PATH_TPL.format(
recipient=message.recipient,
date=datetime.now()
))
make_parent_directories(output_file_path)
with open(output_file_path, u'w') as output_file:
output_file.write(self._encode(rendered_template))
print(self._encode(STDOUT_TEMPLATE.format(**template_vars)))
def make_parent_directories(path):
""" helper Method for creating parent directories. """
parent_dir_path = os.path.dirname(os.path.realpath(path))
try:
os.makedirs(parent_dir_path)
except OSError as exc:
if exc.errno == errno.EEXIST and os.path.isdir(parent_dir_path):
pass
else:
raise