-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
seperating render logic and adding setup.py
- Loading branch information
1 parent
e666e5a
commit 4feea3e
Showing
8 changed files
with
149 additions
and
83 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# flake8: noqa | ||
from .main import EmailInfo, MessageDef, render_email |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import logging | ||
import re | ||
from typing import Dict, NamedTuple | ||
|
||
import chevron | ||
import misaka | ||
from misaka import HtmlRenderer, Markdown | ||
|
||
markdown = Markdown(HtmlRenderer(flags=[misaka.HTML_HARD_WRAP]), extensions=[misaka.EXT_NO_INTRA_EMPHASIS]) | ||
logger = logging.getLogger('morpheus.render') | ||
|
||
|
||
class MessageDef(NamedTuple): | ||
first_name: str | ||
last_name: str | ||
main_template: str | ||
mustache_partials: Dict[str, dict] | ||
macros: Dict[str, dict] | ||
subject_template: str | ||
context: dict | ||
headers: dict | ||
|
||
|
||
class EmailInfo(NamedTuple): | ||
full_name: str | ||
subject: str | ||
html_body: str | ||
headers: dict | ||
|
||
|
||
def _update_context(context, partials, macros): | ||
for k, v in context.items(): | ||
if k.endswith('__md'): | ||
yield k[:-4], markdown(v) | ||
elif k.endswith('__render'): | ||
v = chevron.render( | ||
_apply_macros(v, macros), | ||
data=context, | ||
partials_dict=partials | ||
) | ||
yield k[:-8], markdown(v) | ||
|
||
|
||
def _apply_macros(s, macros): | ||
if macros: | ||
for key, body in macros.items(): | ||
m = re.search('^(\S+)\((.*)\) *$', key) | ||
if not m: | ||
logger.warning('invalid macro "%s", skipping it', key) | ||
continue | ||
name, arg_defs = m.groups() | ||
arg_defs = [a.strip(' ') for a in arg_defs.split('|') if a.strip(' ')] | ||
|
||
def replace_macro(m): | ||
arg_values = [a.strip(' ') for a in m.groups()[0].split('|') if a.strip(' ')] | ||
if len(arg_defs) != len(arg_values): | ||
logger.warning('invalid macro call "%s", not replacing', m.group()) | ||
return m.group() | ||
else: | ||
return chevron.render(body, data=dict(zip(arg_defs, arg_values))) | ||
|
||
s = re.sub(r'%s\((.*?)\)' % name, replace_macro, s) | ||
return s | ||
|
||
|
||
def render_email(m: MessageDef) -> EmailInfo: | ||
full_name = f'{m.first_name or ""} {m.last_name or ""}'.strip(' ') | ||
m.context.setdefault('recipient_name', full_name) | ||
m.context.setdefault('recipient_first_name', m.first_name or full_name) | ||
m.context.setdefault('recipient_last_name', m.last_name) | ||
subject = chevron.render(m.subject_template, data=m.context) | ||
m.context.update( | ||
subject=subject, | ||
**dict(_update_context(m.context, m.mustache_partials, m.macros)) | ||
) | ||
unsubscribe_link = m.context.get('unsubscribe_link') | ||
if unsubscribe_link: | ||
m.headers.setdefault('List-Unsubscribe', f'<{unsubscribe_link}>') | ||
|
||
return EmailInfo( | ||
full_name=full_name, | ||
subject=subject, | ||
html_body=chevron.render( | ||
_apply_macros(m.main_template, m.macros), | ||
data=m.context, | ||
partials_dict=m.mustache_partials, | ||
), | ||
headers=m.headers, | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
from setuptools import setup | ||
|
||
setup( | ||
name='morpheus-mail', | ||
version='0.0.1', | ||
description='Email rendering engine from morpheus', | ||
long_description=""" | ||
Note: this is only installs the rendering logic for morpheus for testing and email preview. | ||
Everything else is excluded to avoid installing unnecessary packages. | ||
""", | ||
classifiers=[ | ||
'Development Status :: 4 - Beta', | ||
'Environment :: Console', | ||
'Programming Language :: Python', | ||
'Programming Language :: Python :: 3', | ||
'Programming Language :: Python :: 3 :: Only', | ||
'Programming Language :: Python :: 3.6', | ||
'Intended Audience :: Developers', | ||
'Intended Audience :: Information Technology', | ||
'Intended Audience :: System Administrators', | ||
'License :: OSI Approved :: MIT License', | ||
'Operating System :: Unix', | ||
'Operating System :: POSIX :: Linux', | ||
'Topic :: Internet', | ||
], | ||
author='Samuel Colvin', | ||
author_email='s@muelcolvin.com', | ||
url='https://github.com/tutorcruncher/morpheus', | ||
license='MIT', | ||
packages=['morpheus.render'], | ||
package_dir={'morpheus.render': 'morpheus/app/render'}, | ||
python_requires='>=3.6', | ||
zip_safe=True, | ||
install_requires=[ | ||
'misaka>=2.1.0', | ||
'chevron>=0.10.0', | ||
], | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters