Mikael Koli пре 4 година
родитељ
комит
be50c73ae3

+ 77 - 7
README.md

@@ -2,17 +2,87 @@
 # Red Mail
 > Next generation email sender
 
------------------
+---
 
 ## What is it?
-Red Mail is an advanced email sender library. 
+Red Mail is an advanced email sender library. It makes sending emails trivial and 
+has a lot of advanced features such as:
+
+- Attachments
+- Templating (via Jinja)
+- Prettified tables
+- Embedded images
+
+## Why Red Mail?
+
+Sending emails should not be this complicated:
+
+```python
+import smtplib
+from email.mime.multipart import MIMEMultipart
+from email.mime.text import MIMEText
+
+msg = MIMEMultipart('alternative')
+msg['Subject'] = f'The contents of {textfile}'
+msg['From'] = 'first.last@gmail.com'
+msg['To'] = 'first.last@example.com'
+
+part1 = MIMEText("Hello!", 'plain')
+part2 = MIMEText("<h1>Hello!</h1>", 'html')
+
+msg.attach(part1)
+msg.attach(part2)
+
+# Send the message via our own SMTP server.
+s = smtplib.SMTP('localhost', port=0)
+s.send_message(msg)
+s.quit()
+```
+
+With Red Mail, it's simple as this:
+
+```python
+from redmail import EmailSender
+
+email = EmailSender(host="localhost", port=0)
+
+email.send(
+    subject="The contents of myfile",
+    receivers=['first.last@example.com'],
+    text="Hello!",
+    html="<h1>Hello!</h1>"
+)
+```
+
+You can also do more advanced things easily with it:
+
+```python
+from redmail import EmailSender
 
-**Core features:**
+email = EmailSender(host="localhost", port=0)
 
-- Attachments: can be dict of dataframes, list of files or dict of bytes
-- Templating: create reusable Jinja templates for your emails 
-- Embedded images: include images straight to the HTML of you emails
-- Embedded tables: include stylished tables to your emails
+email.send(
+    subject="The contents of myfile",
+    sender="me@example.com",
+    receivers=['first.last@example.com'],
+    text="Hello!",
+    html="""<h1>Hello {{ friend }}!</h1>
+        <p>Have you seen this thing</p>
+        {{ awesome_image }}
+        <p>Or this:</p>
+        {{ pretty_table }}
+        <p>Kind regards, {{ sender.full_name }}</p>
+    """,
+    body_params={'friend': 'Jack'},
+    body_images={'awesome_image': 'path/to/image.png'},
+    body_tables={'pretty_table': pd.DataFrame(...)},
+    attachments={
+        'some_data.csv': pd.DataFrame(...),
+        'file_content.html': '<h1>This is an attachment</h1>',
+        'a_file.txt': pathlib.Path('path/to/file.txt')
+    }
+)
+```
 
 ---
 

+ 20 - 0
docs/Makefile

@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS    ?=
+SPHINXBUILD   ?= sphinx-build
+SOURCEDIR     = .
+BUILDDIR      = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+	@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+	@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)

+ 4 - 0
docs/_static/css/colors.css

@@ -0,0 +1,4 @@
+
+.red {
+    color: red;
+}

+ 4 - 0
docs/_static/css/types.css

@@ -0,0 +1,4 @@
+
+.py.class {
+    padding-bottom: 20px;
+}

+ 83 - 0
docs/conf.py

@@ -0,0 +1,83 @@
+# Configuration file for the Sphinx documentation builder.
+#
+# This file only contains a selection of the most common options. For a full
+# list see the documentation:
+# https://www.sphinx-doc.org/en/master/usage/configuration.html
+
+# -- Path setup --------------------------------------------------------------
+
+# If extensions (or modules to document with autodoc) are in another directory,
+# add these directories to sys.path here. If the directory is relative to the
+# documentation root, use os.path.abspath to make it absolute, like shown here.
+#
+import sphinx_rtd_theme
+import os
+import sys
+sys.path.insert(0, os.path.abspath('..'))
+print(f"Root dir: {sys.path[0]}")
+
+# -- Project information -----------------------------------------------------
+
+project = 'redmail'
+copyright = '2022, Mikael Koli'
+author = 'Mikael Koli'
+
+
+# -- General configuration ---------------------------------------------------
+
+# Add any Sphinx extension module names here, as strings. They can be
+# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
+# ones.
+extensions = [
+    'sphinx.ext.doctest',
+    'sphinx.ext.autodoc', 
+    'sphinx.ext.coverage', 
+    'sphinx.ext.napoleon',
+    'sphinx_rtd_theme'
+]
+rst_prolog = """
+.. include:: <s5defs.txt>
+
+"""
+
+
+
+# Extension settings
+
+napoleon_google_docstring = True
+napoleon_numpy_docstring = True
+
+autodoc_typehints = 'none'
+autodoc_member_order = 'bysource'
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+# This pattern also affects html_static_path and html_extra_path.
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+html_logo = "logo.png"
+html_theme_options = {
+    'logo_only': True,
+    'display_version': False,
+}
+
+# -- Options for HTML output -------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+#
+html_title = "Advanced Scheduler for Python"
+html_theme = 'sphinx_rtd_theme'
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+html_css_files = [
+    'css/types.css',
+    'css/colors.css',
+]

BIN
docs/imgs/table_comparison.png


BIN
docs/imgs/table_rendered.png


BIN
docs/imgs/table_unrendered.PNG


BIN
docs/imgs/table_with_style.png


BIN
docs/imgs/table_without_style.png


+ 164 - 0
docs/index.rst

@@ -0,0 +1,164 @@
+
+:red:`Red` Mail
+===============
+
+Red Mail is a Python library for sending emails. 
+It makes sending emails a breeze regardless of if 
+you need to include HTML, embed images or tables or
+attach documents. 
+
+Sending emails is a pretty straight forward task.
+However, the standard SMTP libraries don't make 
+it particularly easy especially if you want to 
+include more than basic text. Red Mail aims to 
+fix this and it makes sending emails a breeze 
+regardless of if you need to include attachments,
+images or prettier HTML.
+
+
+Why Red Mail?
+-------------
+
+Standard SMTP libraries are not very convenient to use. They let you modify any part of the 
+message but simply sending emails **SHOULD NOT** look like this:
+
+.. code-block:: python
+
+    import smtplib
+    from email.mime.multipart import MIMEMultipart
+    from email.mime.text import MIMEText
+
+    msg = MIMEMultipart('alternative')
+    msg['Subject'] = f'The contents of {textfile}'
+    msg['From'] = 'first.last@gmail.com'
+    msg['To'] = 'first.last@example.com'
+
+    part1 = MIMEText("Hello!", 'plain')
+    part2 = MIMEText("<h1>Hello!</h1>", 'html')
+
+    msg.attach(part1)
+    msg.attach(part2)
+
+    # Send the message via our own SMTP server.
+    s = smtplib.SMTP('localhost', port=0)
+    s.send_message(msg)
+    s.quit()
+
+
+It should look like this:
+
+.. code-block:: python
+
+    from redmail import EmailSender
+
+    email = EmailSender(host="localhost", port=0)
+
+    email.send(
+        subject="The contents of myfile",
+        receivers=['first.last@example.com'],
+        text="Hello!",
+        html="<h1>Hello!</h1>"
+    )
+
+Here are also other reasons to use Red Mail:
+
+- :ref:`You can put attachments to the email <attachments>`
+- :ref:`You can include images to the body <embedding-images>`
+- :ref:`You can render nicer tables to the body <embedding-tables>`
+- :ref:`It has Jinja support <jinja-support>`
+- :ref:`You can reuse your HTML templates <templating>`
+- :ref:`Gmail pre-configured <config-gmail>`
+
+In addition, normally tables in emails look like this:
+
+.. image:: /imgs/table_without_style.png
+   :width: 200px
+   
+Red Email styles them like this:
+
+.. image:: /imgs/table_with_style.png
+   :width: 200px
+
+More Examples
+-------------
+
+You could attach things to your email:
+
+.. code-block:: python
+
+    from pathlib import Path
+    import pandas as pd
+
+    email.send(
+        subject="Email subject",
+        receivers=["me@gmail.com"],
+        text_body="Hi, this is a simple email.",
+        attachments={
+            'myfile.csv': Path("path/to/data.csv"),
+            'myfile.xlsx': pd.DataFrame({'A': [1, 2, 3]}),
+            'myfile.html': '<h1>This is content of an attachment</h1>'
+        }
+    )
+
+
+By default, HTML tables in emails look ugly. Red Mail has premade templates
+to turn them more visually pleasing. Just include them as Jinja parameters 
+in body and pass them as Pandas dataframes:
+
+.. code-block:: python
+
+    import pandas as pd
+
+    email.send(
+        subject="Email subject",
+        receivers=["me@gmail.com"],
+        html="""
+            <h1>Hi,</h1> 
+            <p>have you seen this?</p> 
+            {{ mytable }}
+        """,
+        body_tables={"mytable": pd.DataFrame({'a': [1,2,3], 'b': [1,2,3]})}
+    )
+
+You can also include images similarly:
+
+.. code-block: python
+
+    from pathlib import Path
+    import pandas as pd
+
+    email.send(
+        subject="Email subject",
+        receivers=["me@gmail.com"],
+        html="""
+            <h1>Hi,</h1> 
+            <p>have you seen this?</p> 
+            {{ myimg }}
+        """,
+        body_images={"myimg": "path/to/my/image.png"}
+    )
+
+
+Interested?
+-----------
+
+There is much more to offer. Install the package:
+
+.. code-block:: console
+
+    pip install redmail
+
+and read further.
+
+.. toctree::
+   :maxdepth: 2
+   :caption: Contents:
+
+   tutorials/index
+   references
+
+
+Indices and tables
+==================
+
+* :ref:`genindex`


+ 35 - 0
docs/make.bat

@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+	echo.
+	echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+	echo.installed, then set the SPHINXBUILD environment variable to point
+	echo.to the full path of the 'sphinx-build' executable. Alternatively you
+	echo.may add the Sphinx directory to PATH.
+	echo.
+	echo.If you don't have Sphinx installed, grab it from
+	echo.http://sphinx-doc.org/
+	exit /b 1
+)
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd

+ 15 - 0
docs/references.rst

@@ -0,0 +1,15 @@
+References
+==========
+
+Sender
+------
+
+.. autoclass:: redmail.EmailSender
+
+
+Format Classes
+--------------
+
+.. autoclass:: redmail.models.EmailAddress
+
+.. autoclass:: redmail.models.Error

+ 68 - 0
docs/s5defs.txt

@@ -0,0 +1,68 @@
+.. Definitions of interpreted text roles (classes) for S5/HTML data.
+.. This data file has been placed in the public domain.
+
+.. Colours
+   =======
+
+.. role:: black
+.. role:: gray
+.. role:: silver
+.. role:: white
+
+.. role:: maroon
+.. role:: red
+.. role:: magenta
+.. role:: fuchsia
+.. role:: pink
+.. role:: orange
+.. role:: yellow
+.. role:: lime
+.. role:: green
+.. role:: olive
+.. role:: teal
+.. role:: cyan
+.. role:: aqua
+.. role:: blue
+.. role:: navy
+.. role:: purple
+
+
+.. Text Sizes
+   ==========
+
+.. role:: huge
+.. role:: big
+.. role:: small
+.. role:: tiny
+
+
+.. Display in Slides (Presentation Mode) Only
+   ==========================================
+
+.. role:: slide
+   :class: slide-display
+
+
+.. Display in Outline Mode Only
+   ============================
+
+.. role:: outline
+
+
+.. Display in Print Only
+   =====================
+
+.. role:: print
+
+
+.. Display in Handout Mode Only
+   ============================
+
+.. role:: handout
+
+
+.. Incremental Display
+   ===================
+
+.. role:: incremental
+.. default-role:: incremental

+ 50 - 0
docs/tutorials/attachments.rst

@@ -0,0 +1,50 @@
+
+.. _attachments:
+
+Sending Email with Attachments
+------------------------------
+
+Red Mail also provides a convenient way to include
+attachments to the emails, for example:
+
+.. code-block:: python
+
+    import pandas as pd
+    from pathlib import Path
+
+    email.send(
+        subject='Some attachments',
+        receivers=['first.last@example.com'],
+        attachments={
+            'data.csv': Path('path/to/file.csv'), 
+            'data.xlsx': pd.DataFrame(...), 
+            'raw_file.html': '<h1>Just some HTML</h1>',
+        }
+    )
+
+As seen, Red Mail allows passing various objects to the 
+attachments. You may pass a list, a single object or 
+a dict. If you pass a dict, the key is used to determine
+the name of the attachment and possibly the type.
+
+Here is a list of supported value formats if dict is passed:
+
+================ =============== =================================================================
+Value type       Key as          Value as
+================ =============== =================================================================
+``pd.Series``    Attachment name Turned to CSV, XLSX, HTML etc. depending on file extension in key
+``pd.DataFrame`` Attachment name Turned to CSV, XLSX, HTML etc. depending on file extension in key           
+``str``          Attachment name Attachment content as raw text
+``bytes``        Attachment name Attachment content as raw bytes
+``pathlib.Path`` Attachment name Content of the file read as the content of the attachment
+================ =============== =================================================================
+
+Here is a list of supported value formats if list or single object is passed:
+
+================ =============== =========================================================
+Type             Attachment name Value
+================ =============== =========================================================
+``pathlib.Path`` From file name  Content of the file read as the content of the attachment
+``str``          From file name  Considered as file path, handled the same as file path
+================ =============== =========================================================
+

+ 112 - 0
docs/tutorials/body_content.rst

@@ -0,0 +1,112 @@
+
+.. _embedded:
+
+Embedding Content
+=================
+
+Red Mail allows to embed images and tables to the
+HTML bodies of emails. By default, tables often 
+look outdated and ugly in emails but Red Mail
+has pre-made table templates that render nicer
+looking tables from Pandas dataframes.
+
+.. _embedding-tables:
+
+Embedded Tables
+---------------
+
+You may include tables simply by turning them 
+to raw HTML for example using ``df.to_html()``
+in Pandas. However, this often lead to very
+ugly tables as SMTP is poor at handling CSS
+or styling in general. Here is a comparison
+of using ``df.to_html()`` directly vs embedding
+via Red Mail:
+
+|pic1| -- |pic2|
+
+.. |pic1| image:: /imgs/table_unrendered.png
+   :height: 150px
+   :align: top
+   
+
+.. |pic2| image:: /imgs/table_rendered.png
+   :height: 150px
+   :align: top
+
+
+To embed tables, you can si  mply pass them 
+to the send function as Pandas dataframes:
+
+.. code-block:: python
+
+    # Creating a simple dataframe
+    import pandas as pd
+    df = pd.DataFrame({
+        'nums': [1,2,3],
+        'strings': ['yes', 'no', 'yes'],
+    })
+
+    # Let Red Mail to render the dataframe for you:
+    email.send(
+        subject='Some attachments',
+        receivers=['first.last@example.com'],
+        html="<h1>This is a table:</h1> {{ mytable }}",
+        body_tables={
+            'mytable': df, 
+        }
+    )
+
+
+Red Mail uses Jinja and inline HTML styling to make the
+tables look nice. Email servers typically don't handle
+well CSS.
+
+.. warning::
+
+    Red Email Pandas templating should work on various 
+    dataframe strucutres (empty, multi-indexed etc.) but
+    sometimes the rendering may be off if the dataframe
+    is especially complex in structural sense. There are
+    development plans to make it even more better.
+
+.. _embedding-images:
+
+Embedded Images
+---------------
+
+You can also embed images straight to the HTML body 
+of the email:
+
+.. code-block:: python
+
+    email.send(
+        subject='Some attachments',
+        receivers=['first.last@example.com'],
+        html="<h1>This is an image:</h1> {{ myimage }}",
+        body_images={
+            'myimage': 'path/to/image.png', 
+        }
+    )
+
+The image will be rendered as ``<img src="cid:...">``.
+In case you need to control the image (like the size)
+you can also create the ``img`` tag yourself:
+
+.. code-block:: python
+
+    email.send(
+        subject='Some attachments',
+        receivers=['first.last@example.com'],
+        html='<h1>This is an image:</h1> <img src="{{ myimage.src }}">',
+        body_images={
+            'myimage': 'path/to/image.png', 
+        }
+    )
+
+In addition to paths as strings, the following are supported:
+
+- ``pathlib.Path``
+- ``bytes`` (the image as raw bytes)
+- ``matplotlib.pyplot.Figure``
+- ``PIL.Image``

+ 52 - 0
docs/tutorials/cookbook.rst

@@ -0,0 +1,52 @@
+.. _cookbook:
+
+Cook Book
+=========
+
+This section provides various handy tips.
+
+.. _config-gmail:
+
+Gmail
+-----
+
+You need to make an app password `see this Google's answer <https://support.google.com/accounts/answer/185833>`_. 
+When that is done you can use Red Mail's gmail object that has the Gmail
+server pre-configured:
+
+.. code-block:: python
+
+    from redmail import gmail
+    gmail.user_name = 'example@gmail.com' # Your Gmail user
+    gmail.password = '<APP PASSWORD>'
+
+    # And then you can send emails
+    gmail.send(
+        subject="Example email",
+        receivers=['example@gmail.com']
+        text="Hi, this is an email."
+    )
+
+.. note::
+
+    You can only send emails using your Gmail email address. Changing ``sender`` has no effect.
+
+Error Alerts
+------------
+
+If you are building long running program (ie. web app) you can make a
+templated error alerts that include the full traceback:
+
+.. code-block:: python
+
+    from redmail import EmailSender
+    
+    error_email = EmailSender(...)
+    error_email.receivers = ['me@example.com']
+    error_email.html = """<h2>An error encountered</h2>{{ error }}"""
+
+    try:
+        raise RuntimeError("Oops")
+    except:
+        # Send an email including the traceback
+        error_email.send(subject="Fail: doing stuff failed")

+ 57 - 0
docs/tutorials/getting_started.rst

@@ -0,0 +1,57 @@
+.. _getting-started:
+
+Getting started
+===============
+
+Install the package from `Pypi <https://pypi.org/project/redmail/>`_:
+
+.. code-block:: console
+
+    pip install redengine
+
+.. _configure:
+
+Configuring Email
+-----------------
+
+You can configure your sender by:
+
+
+.. code-block:: python
+
+   from redmail import EmailSender
+
+   email = EmailSender(
+       host='<SMTP HOST>',
+       port='<SMTP PORT>',
+       user_name='<USER_NAME>',
+       password='<PASSWORD>'
+   )
+
+If your SMTP server does not require login to send emails then 
+just don't pass ``user_name`` and ``password`` to ``EmailSender``.
+
+Alternatively, if you use Gmail there is a pre-configured sender
+which you can just import and set user name and password:
+
+.. code-block:: python
+
+   from redmail import gmail
+
+   gmail.user_name = 'me@gmail.com'
+   gmail.password = '<PASSWORD>'
+
+Sending Emails
+--------------
+
+You can just send emails by calling the method ``send``:
+
+.. code-block:: python
+
+   email.send(
+       subject='email subject',
+       receivers=['first.last@example.com'],
+       text="Hi, this is an email."
+   )
+
+Next tutorial covers sending emails more thoroughly.

+ 19 - 0
docs/tutorials/index.rst

@@ -0,0 +1,19 @@
+.. _tutorials:
+
+Tutorials
+=========
+
+Welcome to Red Mail's tutorials!
+
+.. toctree::
+   :maxdepth: 1
+   :caption: Contents:
+
+   getting_started
+   sending
+   attachments
+   jinja_support
+   body_content
+   templating
+   cookbook
+

+ 116 - 0
docs/tutorials/jinja_support.rst

@@ -0,0 +1,116 @@
+
+.. _jinja-support:
+
+Jinja Support
+=============
+
+Red Mail uses Jinja for templating the HTML and text 
+bodies. This enables a lot of features out-of-the box.
+See `Jinja documentation <https://jinja.palletsprojects.com/>`_ 
+for more details of the templating.
+
+Parametrizing Emails
+--------------------
+
+You can also parametrize an email using Jinja 
+parameters:
+
+.. code-block:: python
+
+    email.send(
+        subject='email subject',
+        receivers=['first.last@example.com'],
+        html="""
+            <h1>Hi {{ client }},</h1>
+            <p>we are opening the source of {{ project_name }}.</p>
+            <p>Kind regards
+            <br>{{ company }}</p>
+        """,
+        text="""
+            Hi {{ client }},
+            we are opening the source of {{ project_name }}.
+
+            Kind regards,
+            {{ company }}
+        """,
+        body_params={
+            'client': 'Customer LTD', 
+            'project_name': 'Red Mail', 
+            'company': 'Company LTD',
+        }
+    )
+
+Both text and HTML body support Jinja parametrization. 
+
+Default Parameters
+^^^^^^^^^^^^^^^^^^
+
+There are also some parameters passed automatically for convenience.
+You can always override these if you wish. Here is a quick example of
+some of them:
+
+.. code-block:: python
+
+    email.send(
+        subject='email subject',
+        receivers=['first.last@example.com'],
+        html="""
+            <h1>Hi,</h1>
+            <p>nice to meet you</p>
+            <p>Kind regards
+            <br>{{ sender.full_name }}</p>
+        """,
+    )
+
+Here is a list of default parameters:
+
+================ ==================================== =========================================================
+Parameter Name   Class                                Description
+================ ==================================== =========================================================
+sender           :class:`redmail.models.EmailAddress` Format class of the email sender
+error            :class:`redmail.models.Error`        Format class of the current exception (if any)
+node             str                                  Computer’s network name (if can be determined)
+user             str                                  Name of the current user logged on the computer
+now              datetime.datetime                    Current date and time
+================ ==================================== =========================================================
+
+
+Including Loops and Control Flow
+--------------------------------
+
+As the bodies use Jinja in the background, you can use various additional features such 
+as if statements, for loops, macros etc. Here is a quick illustration:
+
+.. code-block:: python
+
+    email.send(
+        subject='email subject',
+        receivers=['first.last@example.com'],
+        html="""
+            <h1>Hi!</h1>
+            <p>
+                Soon you will meet my team. 
+                Here is a quick introduction:
+            </p>
+            <ul>
+                {% for colleague in colleagues.items() %}
+                    <li>{{ colleague }}: {{ description }}</li>
+                {% endfor %}
+            </ul>
+            {% if confidential %}
+                <p>
+                    This message is confidential. 
+                </p>
+            {% endif %}
+
+            <p>Kind regards
+            <br>{{ sender.full_name }}</p>
+        """,
+        body_params={
+            'colleagues': {'Jack': 'Developer', 'John': 'CEO'},
+            'confidential': False
+        }
+    )
+
+Please see `Jinja documentation <https://jinja.palletsprojects.com/>`_ 
+for more.

+ 55 - 0
docs/tutorials/sending.rst

@@ -0,0 +1,55 @@
+.. _sending-emails:
+
+Sending Emails
+==============
+
+This section covers the basics of sending emails.
+We use an ``EmailSender`` configured in :ref:`configure`.
+
+
+Sending Email with Text Body
+----------------------------
+
+To send an email with plain text message:
+
+.. code-block:: python
+
+   email.send(
+       subject='email subject',
+       receivers=['first.last@example.com'],
+       text="Hi, this is an email."
+   )
+
+Sending Email with HTML Body
+----------------------------
+
+To send an email with html content:
+
+.. code-block:: python
+
+    email.send(
+        subject='email subject',
+        receivers=['first.last@example.com'],
+        html="""
+            <h1>Hi,</h1>
+            <p>this is an email.</p>
+        """
+    )
+
+
+Sending Email with text and HTML Body
+-------------------------------------
+
+You can also include both to your email:
+
+.. code-block:: python
+
+    email.send(
+        subject='email subject',
+        receivers=['first.last@example.com'],
+        text="Hi, this is an email.",
+        html="""
+            <h1>Hi,</h1>
+            <p>this is an email.</p>
+        """
+    )

+ 55 - 0
docs/tutorials/templating.rst

@@ -0,0 +1,55 @@
+
+.. _templating:
+
+Using Templates
+===============
+
+As templating relies on Jinja, you can set the 
+template path to a custom folder and 
+
+.. code-block:: python
+
+    from redmail import EmailSender
+    email = EmailSender(host="localhost", port=0)
+    email.set_template_paths(
+        html="path/html/templates",
+        text="path/text/templates",
+    )
+
+.. note::
+
+    If you are dissatisfied with default HTML and text
+    table templates, you can also pass ``html_table``
+    and ``text_table`` to specify the templates used
+    to render embedded tables.
+
+Next we will make a simple template, let's call it 
+``event_card.html``:
+
+.. code-block:: html
+
+    <h1>Hi {{ participant }}!</h1>
+    <p>
+        Thank you for being a valuable member of our 
+        community! We are organizing an event 
+        {{ event_name }} and we would like to invite
+        you.
+    </p>
+    <p>Kind regards,<br>
+    <em>{{ organizer }} </em>
+    </p>
+
+Then we can use this template:
+
+.. code-block:: python
+
+    email.send(
+        subject='email subject',
+        receivers=['first.last@example.com'],
+        html_template='event_card.html',
+        body_params={
+            'participant': 'Jack', 
+            'event_name': 'Open data',
+            'organizer': 'Organization.org'
+        }
+    )

+ 2 - 1
tox.ini

@@ -25,7 +25,8 @@ commands =
 description = invoke sphinx-build to build the HTML docs
 basepython = python3.8
 deps = 
-    -r{toxinidir}/requirements/docs.txt
+    -r{toxinidir}/requirements.txt
+    sphinx_rtd_theme
     sphinx >= 1.7.5
 commands = sphinx-build docs "{toxinidir}/docs/_build/html" --color -W -bhtml {posargs}
            sphinx-build -b doctest docs "{toxinidir}/docs/_build/html"