
Writing Custom TurboMail Extensions
===================================

All implementations of specific behaviors (e.g. managers) can be built using 
TurboMail extensions. The basic extension interface provided by TurboMail is
very simple and takes care of basic life-cycle management:

* The start() method is called before the extension is used the first time. If
  the extension returns True, TurboMail considers it running. If it returns 
  False, some error happened and the extension instance is considered faulty.
* The stop() method is called when the extension is not needed any longer. The
  extension should release any resources (e.g. existing connections or locks)
  but it must not raise any exceptions.

Every extension instance is started and stopped only once. This is being 
guaranteed by the super class so you must call super() for all overriden methods!



Writing Custom Managers
=======================

Every manager has a method get_new_transport() which can be used to get a new
transport instance ready to deliver messages. The manager is responsible to 
manager the lifecycle of the returned transport instance so it needs to call
the stop() method when the transport is not used any more (e.g. the manager's
stop() method was called or the manager wants to replace the existing transport
instance with a new transport.

managers must be thread safe


Writing Custom Transports
=========================

Interface

turbomail.api.Transport

deliver(message)
stop()

helper method config_get(key, default=None, tm2_key=None)
        """Returns the value for the given key from the configuration. If the 
        value was not found, the default value (default None) is returned. If 
        tm2_key was specified, """

transports don't have to be thread safe



.. _html2text:

Clever plain text generation for your rich text messages
========================================================

Every HTML email should have a plain text part. If you really need produce nice
text emails, you should build the plain text part by hand, the same way you do
with the HTML part. But sometimes you just need a text part without much work
(this is especially true if your mails' contents do change frequently). So
TurboMail has its own naïve implementation of an HTML to text converter called 
``TagStripper`` which is applied to your rich text part if you don't provide any
plain text.

There are quite a few, very nice HTML-to-text libraries in the Python space but
we did not feel comfortable including one of them in TurboMail due to licensing
restrictions (TurboMail should be usable under the MIT license), additional
requirements (TurboMail itself should have as few external dependencies as 
possible and some of those converters requires quite a few packages for themselves)
and maintenance (we don't want to ship a private copies of external libraries
which we have to keep secure and up-to-date). So we decided to continue shipping
a simple converter (like in TurboMail 2) but give you the option to add your own.


TagStripper - Do the simplest thing that could possibly work
------------------------------------------------------------

``TagStripper`` is meant to be the simplest implementation of an html to text
converter that is of any use: It just strips the tags from the HTML but does
not touch the contents (so it does not care about HTML entities like &nbsp;)
at all. The only exception to this rule are script, header and style tags -
TagStripper will cut the contents of these tags too because usually they don't
contain any information which is useful for plain text messages.


YourMegaCleverHtmlToTextConverter
---------------------------------

So you want to roll your own HTML to text converter. First of all you encapsulate
your algorithm in a class which inherits from ``BaseHTML2TextConverter``::

  from turbomail.html2text import BaseHTML2TextConverter
  # TODO: Probably this should be moved to the api package
  
  class MyHuperDuperConverter(BaseHTML2TextConverter):
      def convert(self, html_content):
          plain_text = ... # Convert the HTML
          return plain_text
  
After that you can configure TurboMail so that it uses your converter.
# TODO: What API should we make?
# extension point 'turbomail.html2text'
# turbomail.html2text = "MyHuperDuper"
# interface.start(html2text_converters={})

.. _custom_adapters:

Writing Custom Adapters - use TurboMail at new places
=====================================================

adapters must be thread safe, stop and start can be called multiple times, should
not make any difference

We need **you** - How to Contribute
====================================


Future Tasks
============

* Currently TurboMail does not care about queues. A manager may have a queue which
  holds all mails in-memory but this is up to every manager. I would like to see
  a general queue concept with two initial implementations: The InMemoryQueue
  (same as now) and the DiskStorageQueue which tries to ensure that mails never
  get lost.
* Making TurboMail less global. Currently there is *one* manager and *one* 
  transport which are stored in global variables. I like to see support for 
  different 'channels' which may have different strategies of sending messages.
