Index: AUTHORS
===================================================================
--- AUTHORS	(revision 16)
+++ AUTHORS	(revision 16)
@@ -0,0 +1,1 @@
+Francisco de Borja Lopez Rio <borja@codigo23.net>
Index: INSTALL
===================================================================
--- INSTALL	(revision 13)
+++ INSTALL	(revision 16)
@@ -1,3 +1,3 @@
-Postman - installation instructions
+Mailjam - installation instructions
 ===================================
 
@@ -7,7 +7,7 @@
 ---------------------------
 
-So far, the only dependency you will need in order to run postman is Python [1]_
+So far, the only dependency you will need in order to run mailjam is Python [1]_
 
-Postman has been tested with python *2.7.x*, but it should work with versions
+Mailjam has been tested with python *2.7.x*, but it should work with versions
 *2.6.x* too.
 
@@ -15,5 +15,5 @@
 more about how to install python.
 
-Second, install Postman
+Second, install Mailjam
 -----------------------
 
@@ -21,18 +21,18 @@
 ++++++++++++++++++++
 
-You can install Postman using pip [2]_::
+You can install Mailjam using pip [2]_::
 
-  pip install -e https://bitbucket.org/codigo23/postman#egg=postman
+  pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam
 
 .. note::
 
-   Postman has not been recorded/uploaded to pypi [3]_ yet, so, in order
+   Mailjam has not been recorded/uploaded to pypi [3]_ yet, so, in order
    to install it using pip you will have to provide the URL for the public
-   Postman repo.
+   Mailjam repo.
 
 Installing using easy_install
 +++++++++++++++++++++++++++++
 
-You can not install Postman using easy_install [4]_ yet (until we do
+You can not install Mailjam using easy_install [4]_ yet (until we do
 record/upload it to pypi)
 
@@ -40,5 +40,5 @@
 ++++++++++++++++++++++++++++++
 
-You can install Postman inside a virtualenv [5]_. Just create a virtualenv::
+You can install Mailjam inside a virtualenv [5]_. Just create a virtualenv::
 
   virtualenv /path/to/your/env
@@ -55,7 +55,7 @@
      source /path/to/your/env/bin/activate.csh
 
-And, once the environment has been activated, use pip to install Postman::
+And, once the environment has been activated, use pip to install Mailjam::
 
-  env$ pip install -e https://bitbucket.org/codigo23/postman#egg=postman
+  env$ pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam
 
 Installing from sources
@@ -70,12 +70,12 @@
 ***************
 
-The source code of Postman is hosted in bitbucket [6]_. In order to grab
+The source code of Mailjam is hosted in bitbucket [6]_. In order to grab
 the latest sources you need Mercurial [7]_.
 
 To get a copy of the sources, just *clone* the repository::
 
-  hg clone https://bitbucket.org/codigo23/postman postman-repo
+  hg clone https://bitbucket.org/codigo23/mailjam mailjam-repo
 
-Then, go inside the *postman-repo* directory and run::
+Then, go inside the *mailjam-repo* directory and run::
 
   python setup.py install
@@ -87,10 +87,10 @@
    *root* privileges - for example using sudo [8]_)
 
-Setting up Postman
+Setting up Mailjam
 ------------------
 
 TBW
 
-Running Postman
+Running Mailjam
 ---------------
 
@@ -107,5 +107,5 @@
 .. [4] http://peak.telecommunity.com/DevCenter/EasyInstall
 .. [5] http://www.virtualenv.org/en/latest/index.html
-.. [6] https://bitbucket.org/codigo23/postman
+.. [6] https://bitbucket.org/codigo23/mailjam
 .. [7] http://mercurial.selenic.com
 .. [8] http://sudo.ws
Index: README
===================================================================
--- README	(revision 3)
+++ README	(revision 16)
@@ -1,3 +1,3 @@
-Postman - Mailing lists manager
+Mailjam - Mailing lists manager
 ===============================
 
@@ -8,8 +8,8 @@
 ------------
 
-Postman is a mailing list manager. With it you will be able to create mailing
+Mailjam is a mailing list manager. With it you will be able to create mailing
 lists and manage them.
 
-Postman requires a functional MTA [1]_ (Postman has been successfully tested
+Mailjam requires a functional MTA [1]_ (Mailjam has been successfully tested
 with sendmail [2]_ and postfix [3]_ but it should work with other MTA software)
 
@@ -25,5 +25,5 @@
 ----------
 
-If you would like to learn more about Postman (its internals, how it works,
+If you would like to learn more about Mailjam (its internals, how it works,
 etc) take a look at the official documentation inside the docs/ subdirectory
 
Index: bin/mailjam-mta
===================================================================
--- bin/mailjam-mta	(revision 16)
+++ bin/mailjam-mta	(revision 16)
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+#
+# Run the Postman MTA client
+
+import sys
+from postman.mta import MTAClient
+
+def usage():
+    print """
+    Usage: postman-mta address < raw_email_data
+
+    address is a valid mailing list address
+
+    raw_email_data is the raw data (txt) that contains the information of
+    the email to be sent
+    """
+    return True
+
+if __name__ == '__main__':
+    if len(sys.argv) < 2:
+        usage()
+        raise SystemExit
+    try:
+        raw_email = sys.stdin.read()
+    except:
+        usage()
+        raise SystemExit
+    mta_client = MTAClient(address=sys.argv[1])
+    mta_client.get_raw_email(raw_email)
+    mta_client.run()
+
Index: bin/mailjam-server
===================================================================
--- bin/mailjam-server	(revision 16)
+++ bin/mailjam-server	(revision 16)
@@ -0,0 +1,9 @@
+#!/usr/bin/env python
+#
+# Run the Postman XML-RPC server
+
+from postman.daemon import PostmanDaemon
+
+if __name__ == '__main__':
+    daemon = PostmanDaemon()
+    daemon.run()
Index: n/postman-mta
===================================================================
--- bin/postman-mta	(revision 15)
+++ 	(revision )
@@ -1,31 +1,0 @@
-#!/usr/bin/env python
-#
-# Run the Postman MTA client
-
-import sys
-from postman.mta import MTAClient
-
-def usage():
-    print """
-    Usage: postman-mta address < raw_email_data
-
-    address is a valid mailing list address
-
-    raw_email_data is the raw data (txt) that contains the information of
-    the email to be sent
-    """
-    return True
-
-if __name__ == '__main__':
-    if len(sys.argv) < 2:
-        usage()
-        raise SystemExit
-    try:
-        raw_email = sys.stdin.read()
-    except:
-        usage()
-        raise SystemExit
-    mta_client = MTAClient(address=sys.argv[1])
-    mta_client.get_raw_email(raw_email)
-    mta_client.run()
-
Index: n/postman-server
===================================================================
--- bin/postman-server	(revision 15)
+++ 	(revision )
@@ -1,9 +1,0 @@
-#!/usr/bin/env python
-#
-# Run the Postman XML-RPC server
-
-from postman.daemon import PostmanDaemon
-
-if __name__ == '__main__':
-    daemon = PostmanDaemon()
-    daemon.run()
Index: bin/run_tests
===================================================================
--- bin/run_tests	(revision 10)
+++ bin/run_tests	(revision 16)
@@ -1,16 +1,16 @@
 #!/usr/bin/env python
 #
-# Run the tests for the postman package
+# Run the tests for the mailjam package
 
 import os, shutil, sys, unittest
 
 try:
-    from postman.tests import *
+    from mailjam.tests import *
 except ImportError:
     sys.path.append(os.path.join(os.path.dirname(__file__), '../'))
     try:
-        from postman.tests import *
+        from mailjam.tests import *
     except ImportError:
-        raise SystemExit('Could not find postman on your filesystem')
+        raise SystemExit('Could not find mailjam on your filesystem')
 
 try:
@@ -18,4 +18,4 @@
 finally:
     # FIXME: hardcoded path to the tmp directory, we should read this path
-    # from postman/tests/postman.conf
-    shutil.rmtree('/tmp/postman-tests')
+    # from mailjam/tests/mailjam.conf
+    shutil.rmtree('/tmp/mailjam-tests')
Index: conf/mailjam-mta.conf
===================================================================
--- conf/mailjam-mta.conf	(revision 16)
+++ conf/mailjam-mta.conf	(revision 16)
@@ -0,0 +1,13 @@
+#
+# mailjam-mta.conf - Mailjam MTA client configuration file
+#
+
+[server]
+address = localhost
+port = 9876
+uri = http://%(address)s:%(port)s
+ssl = false
+
+[archive]
+persistent = true
+path = /usr/local/mailjam/archive-mta
Index: conf/mailjam.conf
===================================================================
--- conf/mailjam.conf	(revision 16)
+++ conf/mailjam.conf	(revision 16)
@@ -0,0 +1,29 @@
+#
+# mailjam.conf - Mailjam daemon configuration file
+#
+
+[xmlrpc_server]
+address = localhost
+port = 9876
+ssl = false
+ssl_key = /usr/local/etc/mailjam/ssl/mailjam.key
+ssl_crt = /usr/local/etc/mailjam/ssl/mailjam.crt
+logfile = /var/log/mailjam/xmlrpc_server.log
+
+[storage]
+backend = json
+path = /usr/local/mailjam/storage
+lists_db = %(path)s/mailings.%(backend)s
+members_db = %(path)s/members.%(backend)s
+
+[archive]
+enabled = true
+backend = json
+path = /usr/local/mailjam/archives
+
+[mailing_lists]
+private = true
+
+[members]
+auto_signup = false
+allow_chpasswd = false
Index: nf/postman-mta.conf
===================================================================
--- conf/postman-mta.conf	(revision 15)
+++ 	(revision )
@@ -1,13 +1,0 @@
-#
-# postman-mta.conf - Postman MTA client configuration file
-#
-
-[server]
-address = localhost
-port = 9876
-uri = http://%(address)s:%(port)s
-ssl = false
-
-[archive]
-persistent = true
-path = /usr/local/postman/archive-mta
Index: nf/postman.conf
===================================================================
--- conf/postman.conf	(revision 14)
+++ 	(revision )
@@ -1,29 +1,0 @@
-#
-# postman.conf - Postman daemon configuration file
-#
-
-[xmlrpc_server]
-address = localhost
-port = 9876
-ssl = false
-ssl_key = /usr/local/etc/postman/ssl/postman.key
-ssl_crt = /usr/local/etc/postman/ssl/postman.crt
-logfile = /var/log/postman/xmlrpc_server.log
-
-[storage]
-backend = json
-path = /usr/local/postman/storage
-lists_db = %(path)s/mailings.%(backend)s
-members_db = %(path)s/members.%(backend)s
-
-[archive]
-enabled = true
-backend = json
-path = /usr/local/postman/archives
-
-[mailing_lists]
-private = true
-
-[members]
-auto_signup = false
-allow_chpasswd = false
Index: docs/src/_build/html/.buildinfo
===================================================================
--- docs/src/_build/html/.buildinfo	(revision 13)
+++ docs/src/_build/html/.buildinfo	(revision 16)
@@ -1,4 +1,4 @@
 # Sphinx build info version 1
 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: d6b13f3c5a0c2b1ecbf54831463e3bec
+config: ceb77347f0c7a864ec9030a8b3dabfdc
 tags: fbb0d17656682115ca4d033fb2f83ba1
Index: docs/src/_build/html/_sources/configuration.txt
===================================================================
--- docs/src/_build/html/_sources/configuration.txt	(revision 13)
+++ docs/src/_build/html/_sources/configuration.txt	(revision 16)
@@ -6,20 +6,20 @@
 .. _configuration_daemon:
 
-Postman daemon configuration file
+Mailjam daemon configuration file
 ---------------------------------
 
-All the configurations that can be applied to the Postman daemon are registered
-in the **postman.conf** file. That file contains ini-style [1]_ configuration 
+All the configurations that can be applied to the Mailjam daemon are registered
+in the **mailjam.conf** file. That file contains ini-style [1]_ configuration 
 parameters, separated in different *categories*.
 
 .. note::
 
-   The postman.conf file will be installed in different locations depending on
+   The mailjam.conf file will be installed in different locations depending on
    your setup. The usual locations are:
 
-   - */etc/postman.conf* - In most Linux systems (like archlinux, gentoo, 
+   - */etc/mailjam.conf* - In most Linux systems (like archlinux, gentoo, 
      fedora, debian, ubuntu, etc)
 
-   - */usr/local/etc/postman.conf* - In most BSD systems (like FreeBSD, OpenBSD,
+   - */usr/local/etc/mailjam.conf* - In most BSD systems (like FreeBSD, OpenBSD,
      NetBSD, etc)
 
@@ -73,5 +73,5 @@
 *******
 
-Default: ``/usr/local/etc/postman/ssl/postman.key``
+Default: ``/usr/local/etc/mailjam/ssl/mailjam.key``
 
 Path to the ssl key used for encrypted SSL sessions.
@@ -86,5 +86,5 @@
 *******
 
-Default: ``/usr/local/etc/postman/ssl/postman.crt``
+Default: ``/usr/local/etc/mailjam/ssl/mailjam.crt``
 
 Path to the ssl certificate used for encrypted SSL sessions.
@@ -99,5 +99,5 @@
 *******
 
-Default: ``/var/log/postman/xmlrpc_server.log``
+Default: ``/var/log/mailjam/xmlrpc_server.log``
 
 Path to the file where log messages will be saved
@@ -128,5 +128,5 @@
 ****
 
-Default: ``/usr/local/postman/storage``
+Default: ``/usr/local/mailjam/storage``
 
 Path to the directory where the backend will save data.
@@ -137,5 +137,5 @@
 ********
 
-Default: ``/usr/local/postman/storage/mailings.json``
+Default: ``/usr/local/mailjam/storage/mailings.json``
 
 Path to the file where the identifiers of existing mailing lists will be saved.
@@ -165,5 +165,5 @@
 **********
 
-Default: ``/usr/local/postman/storage/members.json``
+Default: ``/usr/local/mailjam/storage/members.json``
 
 Path to the file where the identifiers of existing members will be saved.
@@ -191,5 +191,5 @@
 Default: ``true``
 
-Enables/disables the *archives* feature. When enabled, Postman saves copies of
+Enables/disables the *archives* feature. When enabled, Mailjam saves copies of
 email address into an *archive*, so they can be read later, through a web 
 interface.
@@ -220,5 +220,5 @@
 ****
 
-Default: ``/usr/local/postman/archives``
+Default: ``/usr/local/mailjam/archives``
 
 Path to the directory where the archives will be saved.
@@ -238,5 +238,5 @@
 .. warning::
 
-   This parameters are not currently used in postman, we are still working
+   This parameters are not currently used in mailjam, we are still working
    on per-mailing-list configuration parameters.
 
@@ -265,5 +265,5 @@
 .. warning::
 
-   This parameters are not currently used in postman, we are still working
+   This parameters are not currently used in mailjam, we are still working
    on per-member configuration parameters.
 
Index: docs/src/_build/html/_sources/index.txt
===================================================================
--- docs/src/_build/html/_sources/index.txt	(revision 13)
+++ docs/src/_build/html/_sources/index.txt	(revision 16)
@@ -1,6 +1,6 @@
-Postman official documentation
+Mailjam official documentation
 ==============================
 
-This is the official documentation for Postman_, a mailing list management 
+This is the official documentation for Mailjam_, a mailing list management 
 software written in Python_.
 
@@ -25,4 +25,4 @@
 * :ref:`search`
 
-.. _Postman: https://bitbucket.org/codigo23/postman
+.. _Mailjam: https://bitbucket.org/codigo23/mailjam
 .. _Python: http://python.org
Index: docs/src/_build/html/_sources/install.txt
===================================================================
--- docs/src/_build/html/_sources/install.txt	(revision 13)
+++ docs/src/_build/html/_sources/install.txt	(revision 16)
@@ -9,7 +9,7 @@
 ---------------------------
 
-So far, the only dependency you will need in order to run postman is Python_
+So far, the only dependency you will need in order to run mailjam is Python_
 
-Postman has been tested with python *2.7.x*, but it should work with versions
+Mailjam has been tested with python *2.7.x*, but it should work with versions
 *2.6.x* too.
 
@@ -17,7 +17,7 @@
 more about how to install python.
 
-.. _install_postman:
+.. _install_mailjam:
 
-Second, install Postman
+Second, install Mailjam
 -----------------------
 
@@ -27,12 +27,12 @@
 ++++++++++++++++++++
 
-You can install Postman using pip_::
+You can install Mailjam using pip_::
 
-  pip install -e https://bitbucket.org/codigo23/postman#egg=postman
+  pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam
 
 .. note::
 
-   Postman has not been recorded/uploaded to pypi_ yet, so, in order to install 
-   it using pip you will have to provide the URL for the public Postman repo.
+   Mailjam has not been recorded/uploaded to pypi_ yet, so, in order to install 
+   it using pip you will have to provide the URL for the public Mailjam repo.
 
 .. _install_with_easy_install:
@@ -41,5 +41,5 @@
 +++++++++++++++++++++++++++++
 
-You can not install Postman using easy_install_ yet (until we do record/upload 
+You can not install Mailjam using easy_install_ yet (until we do record/upload 
 it to pypi)
 
@@ -49,5 +49,5 @@
 ++++++++++++++++++++++++++++++
 
-You can install Postman inside a virtualenv_. Just create a virtualenv::
+You can install Mailjam inside a virtualenv_. Just create a virtualenv::
 
   virtualenv /path/to/your/env
@@ -64,7 +64,7 @@
      source /path/to/your/env/bin/activate.csh
 
-And, once the environment has been activated, use pip to install Postman::
+And, once the environment has been activated, use pip to install Mailjam::
 
-  env$ pip install -e https://bitbucket.org/codigo23/postman#egg=postman
+  env$ pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam
 
 .. _install_from_sources:
@@ -89,12 +89,12 @@
 ***************
 
-The source code of Postman is hosted in bitbucket_ [1]_. In order to grab
+The source code of Mailjam is hosted in bitbucket_ [1]_. In order to grab
 the latest sources you need Mercurial_.
 
 To get a copy of the sources, just *clone* the repository::
 
-  hg clone https://bitbucket.org/codigo23/postman postman-repo
+  hg clone https://bitbucket.org/codigo23/mailjam mailjam-repo
 
-Then, go inside the *postman-repo* directory and run::
+Then, go inside the *mailjam-repo* directory and run::
 
   python setup.py install
@@ -110,14 +110,14 @@
    This process will work inside a virtualenv_ too.
 
-.. _install_setting_up_postman:
+.. _install_setting_up_mailjam:
 
-Setting up Postman
+Setting up Mailjam
 ------------------
 
 TBW
 
-.. _install_running_postman:
+.. _install_running_mailjam:
 
-Running Postman
+Running Mailjam
 ---------------
 
@@ -140,3 +140,3 @@
 .. _sudo: http://sudo.ws
 
-.. [1] https://bitbucket.org/codigo23/postman
+.. [1] https://bitbucket.org/codigo23/mailjam
Index: docs/src/_build/html/_sources/overview.txt
===================================================================
--- docs/src/_build/html/_sources/overview.txt	(revision 13)
+++ docs/src/_build/html/_sources/overview.txt	(revision 16)
@@ -1,3 +1,3 @@
-Overview of postman's architecture
+Overview of mailjam's architecture
 ==================================
 
@@ -7,5 +7,5 @@
 ------------
 
-Postman has been designed following a **multi-component structure**. There is 
+Mailjam has been designed following a **multi-component structure**. There is 
 **a daemon** that manage the mailing lists and members information in a storage
 backend and there are **different kinds of clients** (currently, three of them)
@@ -14,12 +14,12 @@
 This is the scheme of the architecture:
 
-.. image:: /postman_architecture.png
-   :alt: Scheme of the architecture behind Postman
+.. image:: /mailjam_architecture.png
+   :alt: Scheme of the architecture behind Mailjam
    :class: open_fancybox
 
 
-.. _overview_postman_daemon:
+.. _overview_mailjam_daemon:
 
-Postman daemon
+Mailjam daemon
 --------------
 
@@ -32,5 +32,5 @@
 to add/update/delete data from the backend.
 
-.. _overview_postman_mta_client:
+.. _overview_mailjam_mta_client:
 
 MTA client
@@ -41,5 +41,5 @@
 backend to tell the MTA what it has to do with the incoming emails.
 
-.. _overview_postman_cli_client:
+.. _overview_mailjam_cli_client:
 
 CLI client
@@ -47,7 +47,7 @@
 
 This is a shell-like interface that can be used to add mailing lists to a given
-Postman server, edit such mailing lists information, add members, etc. 
+Mailjam server, edit such mailing lists information, add members, etc. 
 
-.. _overview_postman_web_client:
+.. _overview_mailjam_web_client:
 
 Web client
@@ -56,3 +56,3 @@
 This is a small *webapp* that can be used to perform the same management 
 operations you can achieve using the 
-:ref:`CLI client<overview_postman_cli_client>`.
+:ref:`CLI client<overview_mailjam_cli_client>`.
Index: docs/src/_build/html/_sources/running.txt
===================================================================
--- docs/src/_build/html/_sources/running.txt	(revision 13)
+++ docs/src/_build/html/_sources/running.txt	(revision 16)
@@ -1,3 +1,3 @@
-Running Postman
+Running Mailjam
 ===============
 
Index: docs/src/_build/html/configuration.html
===================================================================
--- docs/src/_build/html/configuration.html	(revision 13)
+++ docs/src/_build/html/configuration.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Configuration &mdash; Postman 0.1.0 documentation</title>
+    <title>Configuration &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,6 +26,6 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
-    <link rel="next" title="Running Postman" href="running.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
+    <link rel="next" title="Running Mailjam" href="running.html" />
     <link rel="prev" title="Installation instructions" href="install.html" /> 
   </head>
@@ -38,10 +38,10 @@
              accesskey="I">index</a></li>
         <li class="right" >
-          <a href="running.html" title="Running Postman"
+          <a href="running.html" title="Running Mailjam"
              accesskey="N">next</a> |</li>
         <li class="right" >
           <a href="install.html" title="Installation instructions"
              accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -58,5 +58,5 @@
 <ul class="simple">
 <li><a class="reference internal" href="#configuration" id="id9">Configuration</a><ul>
-<li><a class="reference internal" href="#postman-daemon-configuration-file" id="id10">Postman daemon configuration file</a><ul>
+<li><a class="reference internal" href="#mailjam-daemon-configuration-file" id="id10">Mailjam daemon configuration file</a><ul>
 <li><a class="reference internal" href="#xmlrpc-server" id="id11">xmlrpc_server</a><ul>
 <li><a class="reference internal" href="#address" id="id12">address</a></li>
@@ -96,17 +96,17 @@
 </ul>
 </div>
-<div class="section" id="postman-daemon-configuration-file">
-<span id="configuration-daemon"></span><h2><a class="toc-backref" href="#id10">Postman daemon configuration file</a><a class="headerlink" href="#postman-daemon-configuration-file" title="Permalink to this headline">¶</a></h2>
-<p>All the configurations that can be applied to the Postman daemon are registered
-in the <strong>postman.conf</strong> file. That file contains ini-style <a class="footnote-reference" href="#id6" id="id1">[1]</a> configuration
+<div class="section" id="mailjam-daemon-configuration-file">
+<span id="configuration-daemon"></span><h2><a class="toc-backref" href="#id10">Mailjam daemon configuration file</a><a class="headerlink" href="#mailjam-daemon-configuration-file" title="Permalink to this headline">¶</a></h2>
+<p>All the configurations that can be applied to the Mailjam daemon are registered
+in the <strong>mailjam.conf</strong> file. That file contains ini-style <a class="footnote-reference" href="#id6" id="id1">[1]</a> configuration
 parameters, separated in different <em>categories</em>.</p>
 <div class="admonition note">
 <p class="first admonition-title">Note</p>
-<p>The postman.conf file will be installed in different locations depending on
+<p>The mailjam.conf file will be installed in different locations depending on
 your setup. The usual locations are:</p>
 <ul class="simple">
-<li><em>/etc/postman.conf</em> - In most Linux systems (like archlinux, gentoo,
+<li><em>/etc/mailjam.conf</em> - In most Linux systems (like archlinux, gentoo,
 fedora, debian, ubuntu, etc)</li>
-<li><em>/usr/local/etc/postman.conf</em> - In most BSD systems (like FreeBSD, OpenBSD,
+<li><em>/usr/local/etc/mailjam.conf</em> - In most BSD systems (like FreeBSD, OpenBSD,
 NetBSD, etc)</li>
 </ul>
@@ -140,5 +140,5 @@
 <div class="section" id="ssl-key">
 <span id="configuration-daemon-xmlrpc-ssl-key"></span><h4><a class="toc-backref" href="#id15">ssl_key</a><a class="headerlink" href="#ssl-key" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/etc/postman/ssl/postman.key</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/etc/mailjam/ssl/mailjam.key</span></tt></p>
 <p>Path to the ssl key used for encrypted SSL sessions.</p>
 <div class="admonition warning">
@@ -149,5 +149,5 @@
 <div class="section" id="ssl-crt">
 <span id="configuration-daemon-xmlrpc-ssl-crt"></span><h4><a class="toc-backref" href="#id16">ssl_crt</a><a class="headerlink" href="#ssl-crt" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/etc/postman/ssl/postman.crt</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/etc/mailjam/ssl/mailjam.crt</span></tt></p>
 <p>Path to the ssl certificate used for encrypted SSL sessions.</p>
 <div class="admonition warning">
@@ -158,5 +158,5 @@
 <div class="section" id="logfile">
 <span id="configuration-daemon-xmlrpc-logfile"></span><h4><a class="toc-backref" href="#id17">logfile</a><a class="headerlink" href="#logfile" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/var/log/postman/xmlrpc_server.log</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/var/log/mailjam/xmlrpc_server.log</span></tt></p>
 <p>Path to the file where log messages will be saved</p>
 </div>
@@ -175,10 +175,10 @@
 <div class="section" id="path">
 <span id="configuration-daemon-xmlrpc-path"></span><h4><a class="toc-backref" href="#id20">path</a><a class="headerlink" href="#path" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/postman/storage</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/mailjam/storage</span></tt></p>
 <p>Path to the directory where the backend will save data.</p>
 </div>
 <div class="section" id="lists-db">
 <span id="configuration-daemon-storage-lists-db"></span><h4><a class="toc-backref" href="#id21">lists_db</a><a class="headerlink" href="#lists-db" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/postman/storage/mailings.json</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/mailjam/storage/mailings.json</span></tt></p>
 <p>Path to the file where the identifiers of existing mailing lists will be saved.</p>
 <div class="admonition note">
@@ -201,5 +201,5 @@
 <div class="section" id="members-db">
 <span id="configuration-daemon-xmlrpc-members-db"></span><h4><a class="toc-backref" href="#id22">members_db</a><a class="headerlink" href="#members-db" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/postman/storage/members.json</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/mailjam/storage/members.json</span></tt></p>
 <p>Path to the file where the identifiers of existing members will be saved.</p>
 <div class="admonition note">
@@ -218,5 +218,5 @@
 <span id="configuration-daemon-archive-enabled"></span><h4><a class="toc-backref" href="#id24">enabled</a><a class="headerlink" href="#enabled" title="Permalink to this headline">¶</a></h4>
 <p>Default: <tt class="docutils literal"><span class="pre">true</span></tt></p>
-<p>Enables/disables the <em>archives</em> feature. When enabled, Postman saves copies of
+<p>Enables/disables the <em>archives</em> feature. When enabled, Mailjam saves copies of
 email address into an <em>archive</em>, so they can be read later, through a web
 interface.</p>
@@ -239,5 +239,5 @@
 <div class="section" id="configuration-daemon-archive-path">
 <span id="id5"></span><h4><a class="toc-backref" href="#id26">path</a><a class="headerlink" href="#configuration-daemon-archive-path" title="Permalink to this headline">¶</a></h4>
-<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/postman/archives</span></tt></p>
+<p>Default: <tt class="docutils literal"><span class="pre">/usr/local/mailjam/archives</span></tt></p>
 <p>Path to the directory where the archives will be saved.</p>
 <div class="admonition warning">
@@ -253,5 +253,5 @@
 <div class="admonition warning">
 <p class="first admonition-title">Warning</p>
-<p class="last">This parameters are not currently used in postman, we are still working
+<p class="last">This parameters are not currently used in mailjam, we are still working
 on per-mailing-list configuration parameters.</p>
 </div>
@@ -271,5 +271,5 @@
 <div class="admonition warning">
 <p class="first admonition-title">Warning</p>
-<p class="last">This parameters are not currently used in postman, we are still working
+<p class="last">This parameters are not currently used in mailjam, we are still working
 on per-member configuration parameters.</p>
 </div>
@@ -322,5 +322,5 @@
   <ul>
 <li><a class="reference internal" href="#">Configuration</a><ul>
-<li><a class="reference internal" href="#postman-daemon-configuration-file">Postman daemon configuration file</a><ul>
+<li><a class="reference internal" href="#mailjam-daemon-configuration-file">Mailjam daemon configuration file</a><ul>
 <li><a class="reference internal" href="#xmlrpc-server">xmlrpc_server</a><ul>
 <li><a class="reference internal" href="#address">address</a></li>
@@ -365,5 +365,5 @@
   <h4>Next topic</h4>
   <p class="topless"><a href="running.html"
-                        title="next chapter">Running Postman</a></p>
+                        title="next chapter">Running Mailjam</a></p>
   <h3>This Page</h3>
   <ul class="this-page-menu">
@@ -395,10 +395,10 @@
              >index</a></li>
         <li class="right" >
-          <a href="running.html" title="Running Postman"
+          <a href="running.html" title="Running Mailjam"
              >next</a> |</li>
         <li class="right" >
           <a href="install.html" title="Installation instructions"
              >previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/development.html
===================================================================
--- docs/src/_build/html/development.html	(revision 13)
+++ docs/src/_build/html/development.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Developers documentation &mdash; Postman 0.1.0 documentation</title>
+    <title>Developers documentation &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,5 +26,5 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
     <link rel="prev" title="Some examples" href="examples.html" /> 
   </head>
@@ -39,5 +39,5 @@
           <a href="examples.html" title="Some examples"
              accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -98,5 +98,5 @@
           <a href="examples.html" title="Some examples"
              >previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/examples.html
===================================================================
--- docs/src/_build/html/examples.html	(revision 13)
+++ docs/src/_build/html/examples.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Some examples &mdash; Postman 0.1.0 documentation</title>
+    <title>Some examples &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,7 +26,7 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
     <link rel="next" title="Developers documentation" href="development.html" />
-    <link rel="prev" title="Running Postman" href="running.html" /> 
+    <link rel="prev" title="Running Mailjam" href="running.html" /> 
   </head>
   <body>
@@ -41,7 +41,7 @@
              accesskey="N">next</a> |</li>
         <li class="right" >
-          <a href="running.html" title="Running Postman"
+          <a href="running.html" title="Running Mailjam"
              accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -70,5 +70,5 @@
   <h4>Previous topic</h4>
   <p class="topless"><a href="running.html"
-                        title="previous chapter">Running Postman</a></p>
+                        title="previous chapter">Running Mailjam</a></p>
   <h4>Next topic</h4>
   <p class="topless"><a href="development.html"
@@ -106,7 +106,7 @@
              >next</a> |</li>
         <li class="right" >
-          <a href="running.html" title="Running Postman"
+          <a href="running.html" title="Running Mailjam"
              >previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/genindex.html
===================================================================
--- docs/src/_build/html/genindex.html	(revision 13)
+++ docs/src/_build/html/genindex.html	(revision 16)
@@ -11,5 +11,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Index &mdash; Postman 0.1.0 documentation</title>
+    <title>Index &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -28,5 +28,5 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" /> 
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" /> 
   </head>
   <body>
@@ -37,5 +37,5 @@
           <a href="#" title="General Index"
              accesskey="I">index</a></li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -85,5 +85,5 @@
           <a href="#" title="General Index"
              >index</a></li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/index.html
===================================================================
--- docs/src/_build/html/index.html	(revision 13)
+++ docs/src/_build/html/index.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Postman official documentation &mdash; Postman 0.1.0 documentation</title>
+    <title>Mailjam official documentation &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,6 +26,6 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="#" />
-    <link rel="next" title="Overview of postman’s architecture" href="overview.html" /> 
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="#" />
+    <link rel="next" title="Overview of mailjam’s architecture" href="overview.html" /> 
   </head>
   <body>
@@ -37,7 +37,7 @@
              accesskey="I">index</a></li>
         <li class="right" >
-          <a href="overview.html" title="Overview of postman’s architecture"
+          <a href="overview.html" title="Overview of mailjam’s architecture"
              accesskey="N">next</a> |</li>
-        <li><a href="#">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="#">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -48,14 +48,14 @@
           <div class="body">
             
-  <div class="section" id="postman-official-documentation">
-<h1>Postman official documentation<a class="headerlink" href="#postman-official-documentation" title="Permalink to this headline">¶</a></h1>
-<p>This is the official documentation for <a class="reference external" href="https://bitbucket.org/codigo23/postman">Postman</a>, a mailing list management
+  <div class="section" id="mailjam-official-documentation">
+<h1>Mailjam official documentation<a class="headerlink" href="#mailjam-official-documentation" title="Permalink to this headline">¶</a></h1>
+<p>This is the official documentation for <a class="reference external" href="https://bitbucket.org/codigo23/mailjam">Mailjam</a>, a mailing list management
 software written in <a class="reference external" href="http://python.org">Python</a>.</p>
 <p>Contents:</p>
 <div class="toctree-wrapper compound">
 <ul>
-<li class="toctree-l1"><a class="reference internal" href="overview.html">Overview of postman&#8217;s architecture</a><ul>
+<li class="toctree-l1"><a class="reference internal" href="overview.html">Overview of mailjam&#8217;s architecture</a><ul>
 <li class="toctree-l2"><a class="reference internal" href="overview.html#introduction">Introduction</a></li>
-<li class="toctree-l2"><a class="reference internal" href="overview.html#postman-daemon">Postman daemon</a></li>
+<li class="toctree-l2"><a class="reference internal" href="overview.html#mailjam-daemon">Mailjam daemon</a></li>
 <li class="toctree-l2"><a class="reference internal" href="overview.html#mta-client">MTA client</a></li>
 <li class="toctree-l2"><a class="reference internal" href="overview.html#cli-client">CLI client</a></li>
@@ -65,15 +65,15 @@
 <li class="toctree-l1"><a class="reference internal" href="install.html">Installation instructions</a><ul>
 <li class="toctree-l2"><a class="reference internal" href="install.html#first-install-dependencies">First, install dependencies</a></li>
-<li class="toctree-l2"><a class="reference internal" href="install.html#second-install-postman">Second, install Postman</a></li>
-<li class="toctree-l2"><a class="reference internal" href="install.html#setting-up-postman">Setting up Postman</a></li>
-<li class="toctree-l2"><a class="reference internal" href="install.html#running-postman">Running Postman</a></li>
+<li class="toctree-l2"><a class="reference internal" href="install.html#second-install-mailjam">Second, install Mailjam</a></li>
+<li class="toctree-l2"><a class="reference internal" href="install.html#setting-up-mailjam">Setting up Mailjam</a></li>
+<li class="toctree-l2"><a class="reference internal" href="install.html#running-mailjam">Running Mailjam</a></li>
 <li class="toctree-l2"><a class="reference internal" href="install.html#running-tests-developers-only">Running tests (developers only)</a></li>
 </ul>
 </li>
 <li class="toctree-l1"><a class="reference internal" href="configuration.html">Configuration</a><ul>
-<li class="toctree-l2"><a class="reference internal" href="configuration.html#postman-daemon-configuration-file">Postman daemon configuration file</a></li>
+<li class="toctree-l2"><a class="reference internal" href="configuration.html#mailjam-daemon-configuration-file">Mailjam daemon configuration file</a></li>
 </ul>
 </li>
-<li class="toctree-l1"><a class="reference internal" href="running.html">Running Postman</a></li>
+<li class="toctree-l1"><a class="reference internal" href="running.html">Running Mailjam</a></li>
 <li class="toctree-l1"><a class="reference internal" href="examples.html">Some examples</a></li>
 <li class="toctree-l1"><a class="reference internal" href="development.html">Developers documentation</a></li>
@@ -98,5 +98,5 @@
   <h3><a href="#">Table Of Contents</a></h3>
   <ul>
-<li><a class="reference internal" href="#">Postman official documentation</a><ul>
+<li><a class="reference internal" href="#">Mailjam official documentation</a><ul>
 </ul>
 </li>
@@ -106,5 +106,5 @@
   <h4>Next topic</h4>
   <p class="topless"><a href="overview.html"
-                        title="next chapter">Overview of postman&#8217;s architecture</a></p>
+                        title="next chapter">Overview of mailjam&#8217;s architecture</a></p>
   <h3>This Page</h3>
   <ul class="this-page-menu">
@@ -136,7 +136,7 @@
              >index</a></li>
         <li class="right" >
-          <a href="overview.html" title="Overview of postman’s architecture"
+          <a href="overview.html" title="Overview of mailjam’s architecture"
              >next</a> |</li>
-        <li><a href="#">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="#">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/install.html
===================================================================
--- docs/src/_build/html/install.html	(revision 13)
+++ docs/src/_build/html/install.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Installation instructions &mdash; Postman 0.1.0 documentation</title>
+    <title>Installation instructions &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,7 +26,7 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
     <link rel="next" title="Configuration" href="configuration.html" />
-    <link rel="prev" title="Overview of postman’s architecture" href="overview.html" /> 
+    <link rel="prev" title="Overview of mailjam’s architecture" href="overview.html" /> 
   </head>
   <body>
@@ -41,7 +41,7 @@
              accesskey="N">next</a> |</li>
         <li class="right" >
-          <a href="overview.html" title="Overview of postman’s architecture"
+          <a href="overview.html" title="Overview of mailjam’s architecture"
              accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -59,5 +59,5 @@
 <li><a class="reference internal" href="#installation-instructions" id="id3">Installation instructions</a><ul>
 <li><a class="reference internal" href="#first-install-dependencies" id="id4">First, install dependencies</a></li>
-<li><a class="reference internal" href="#second-install-postman" id="id5">Second, install Postman</a><ul>
+<li><a class="reference internal" href="#second-install-mailjam" id="id5">Second, install Mailjam</a><ul>
 <li><a class="reference internal" href="#installing-using-pip" id="id6">Installing using pip</a></li>
 <li><a class="reference internal" href="#installing-using-easy-install" id="id7">Installing using easy_install</a></li>
@@ -70,6 +70,6 @@
 </ul>
 </li>
-<li><a class="reference internal" href="#setting-up-postman" id="id12">Setting up Postman</a></li>
-<li><a class="reference internal" href="#running-postman" id="id13">Running Postman</a></li>
+<li><a class="reference internal" href="#setting-up-mailjam" id="id12">Setting up Mailjam</a></li>
+<li><a class="reference internal" href="#running-mailjam" id="id13">Running Mailjam</a></li>
 <li><a class="reference internal" href="#running-tests-developers-only" id="id14">Running tests (developers only)</a></li>
 </ul>
@@ -79,31 +79,31 @@
 <div class="section" id="first-install-dependencies">
 <span id="install-dependencies"></span><h2><a class="toc-backref" href="#id4">First, install dependencies</a><a class="headerlink" href="#first-install-dependencies" title="Permalink to this headline">¶</a></h2>
-<p>So far, the only dependency you will need in order to run postman is <a class="reference external" href="http://python.org">Python</a></p>
-<p>Postman has been tested with python <em>2.7.x</em>, but it should work with versions
+<p>So far, the only dependency you will need in order to run mailjam is <a class="reference external" href="http://python.org">Python</a></p>
+<p>Mailjam has been tested with python <em>2.7.x</em>, but it should work with versions
 <em>2.6.x</em> too.</p>
 <p>Please, refer to your operating system package system documentation to learn
 more about how to install python.</p>
 </div>
-<div class="section" id="second-install-postman">
-<span id="install-postman"></span><h2><a class="toc-backref" href="#id5">Second, install Postman</a><a class="headerlink" href="#second-install-postman" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="second-install-mailjam">
+<span id="install-mailjam"></span><h2><a class="toc-backref" href="#id5">Second, install Mailjam</a><a class="headerlink" href="#second-install-mailjam" title="Permalink to this headline">¶</a></h2>
 <div class="section" id="installing-using-pip">
 <span id="install-with-pip"></span><h3><a class="toc-backref" href="#id6">Installing using pip</a><a class="headerlink" href="#installing-using-pip" title="Permalink to this headline">¶</a></h3>
-<p>You can install Postman using <a class="reference external" href="http://www.pip-installer.org/en/latest/index.html">pip</a>:</p>
-<div class="highlight-python"><pre>pip install -e https://bitbucket.org/codigo23/postman#egg=postman</pre>
+<p>You can install Mailjam using <a class="reference external" href="http://www.pip-installer.org/en/latest/index.html">pip</a>:</p>
+<div class="highlight-python"><pre>pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam</pre>
 </div>
 <div class="admonition note">
 <p class="first admonition-title">Note</p>
-<p class="last">Postman has not been recorded/uploaded to <a class="reference external" href="http://pypi.python.org/pypi">pypi</a> yet, so, in order to install
-it using pip you will have to provide the URL for the public Postman repo.</p>
+<p class="last">Mailjam has not been recorded/uploaded to <a class="reference external" href="http://pypi.python.org/pypi">pypi</a> yet, so, in order to install
+it using pip you will have to provide the URL for the public Mailjam repo.</p>
 </div>
 </div>
 <div class="section" id="installing-using-easy-install">
 <span id="install-with-easy-install"></span><h3><a class="toc-backref" href="#id7">Installing using easy_install</a><a class="headerlink" href="#installing-using-easy-install" title="Permalink to this headline">¶</a></h3>
-<p>You can not install Postman using <a class="reference external" href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a> yet (until we do record/upload
+<p>You can not install Mailjam using <a class="reference external" href="http://peak.telecommunity.com/DevCenter/EasyInstall">easy_install</a> yet (until we do record/upload
 it to pypi)</p>
 </div>
 <div class="section" id="installing-inside-a-virtualenv">
 <span id="install-inside-virtualenv"></span><h3><a class="toc-backref" href="#id8">Installing inside a virtualenv</a><a class="headerlink" href="#installing-inside-a-virtualenv" title="Permalink to this headline">¶</a></h3>
-<p>You can install Postman inside a <a class="reference external" href="http://www.virtualenv.org/en/latest/index.html">virtualenv</a>. Just create a virtualenv:</p>
+<p>You can install Mailjam inside a <a class="reference external" href="http://www.virtualenv.org/en/latest/index.html">virtualenv</a>. Just create a virtualenv:</p>
 <div class="highlight-python"><div class="highlight"><pre><span class="n">virtualenv</span> <span class="o">/</span><span class="n">path</span><span class="o">/</span><span class="n">to</span><span class="o">/</span><span class="n">your</span><span class="o">/</span><span class="n">env</span>
 </pre></div>
@@ -121,6 +121,6 @@
 </div>
 </div>
-<p>And, once the environment has been activated, use pip to install Postman:</p>
-<div class="highlight-python"><pre>env$ pip install -e https://bitbucket.org/codigo23/postman#egg=postman</pre>
+<p>And, once the environment has been activated, use pip to install Mailjam:</p>
+<div class="highlight-python"><pre>env$ pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam</pre>
 </div>
 </div>
@@ -136,10 +136,10 @@
 <div class="section" id="from-repository">
 <span id="install-from-repository"></span><h4><a class="toc-backref" href="#id11">From repository</a><a class="headerlink" href="#from-repository" title="Permalink to this headline">¶</a></h4>
-<p>The source code of Postman is hosted in <a class="reference external" href="https://bitbucket.org">bitbucket</a> <a class="footnote-reference" href="#id2" id="id1">[1]</a>. In order to grab
+<p>The source code of Mailjam is hosted in <a class="reference external" href="https://bitbucket.org">bitbucket</a> <a class="footnote-reference" href="#id2" id="id1">[1]</a>. In order to grab
 the latest sources you need <a class="reference external" href="http://mercurial.selenic.com">Mercurial</a>.</p>
 <p>To get a copy of the sources, just <em>clone</em> the repository:</p>
-<div class="highlight-python"><pre>hg clone https://bitbucket.org/codigo23/postman postman-repo</pre>
-</div>
-<p>Then, go inside the <em>postman-repo</em> directory and run:</p>
+<div class="highlight-python"><pre>hg clone https://bitbucket.org/codigo23/mailjam mailjam-repo</pre>
+</div>
+<p>Then, go inside the <em>mailjam-repo</em> directory and run:</p>
 <div class="highlight-python"><pre>python setup.py install</pre>
 </div>
@@ -157,10 +157,10 @@
 </div>
 </div>
-<div class="section" id="setting-up-postman">
-<span id="install-setting-up-postman"></span><h2><a class="toc-backref" href="#id12">Setting up Postman</a><a class="headerlink" href="#setting-up-postman" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="setting-up-mailjam">
+<span id="install-setting-up-mailjam"></span><h2><a class="toc-backref" href="#id12">Setting up Mailjam</a><a class="headerlink" href="#setting-up-mailjam" title="Permalink to this headline">¶</a></h2>
 <p>TBW</p>
 </div>
-<div class="section" id="running-postman">
-<span id="install-running-postman"></span><h2><a class="toc-backref" href="#id13">Running Postman</a><a class="headerlink" href="#running-postman" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="running-mailjam">
+<span id="install-running-mailjam"></span><h2><a class="toc-backref" href="#id13">Running Mailjam</a><a class="headerlink" href="#running-mailjam" title="Permalink to this headline">¶</a></h2>
 <p>TBW</p>
 </div>
@@ -171,5 +171,5 @@
 <colgroup><col class="label" /><col /></colgroup>
 <tbody valign="top">
-<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td><a class="reference external" href="https://bitbucket.org/codigo23/postman">https://bitbucket.org/codigo23/postman</a></td></tr>
+<tr><td class="label"><a class="fn-backref" href="#id1">[1]</a></td><td><a class="reference external" href="https://bitbucket.org/codigo23/mailjam">https://bitbucket.org/codigo23/mailjam</a></td></tr>
 </tbody>
 </table>
@@ -187,5 +187,5 @@
 <li><a class="reference internal" href="#">Installation instructions</a><ul>
 <li><a class="reference internal" href="#first-install-dependencies">First, install dependencies</a></li>
-<li><a class="reference internal" href="#second-install-postman">Second, install Postman</a><ul>
+<li><a class="reference internal" href="#second-install-mailjam">Second, install Mailjam</a><ul>
 <li><a class="reference internal" href="#installing-using-pip">Installing using pip</a></li>
 <li><a class="reference internal" href="#installing-using-easy-install">Installing using easy_install</a></li>
@@ -198,6 +198,6 @@
 </ul>
 </li>
-<li><a class="reference internal" href="#setting-up-postman">Setting up Postman</a></li>
-<li><a class="reference internal" href="#running-postman">Running Postman</a></li>
+<li><a class="reference internal" href="#setting-up-mailjam">Setting up Mailjam</a></li>
+<li><a class="reference internal" href="#running-mailjam">Running Mailjam</a></li>
 <li><a class="reference internal" href="#running-tests-developers-only">Running tests (developers only)</a></li>
 </ul>
@@ -207,5 +207,5 @@
   <h4>Previous topic</h4>
   <p class="topless"><a href="overview.html"
-                        title="previous chapter">Overview of postman&#8217;s architecture</a></p>
+                        title="previous chapter">Overview of mailjam&#8217;s architecture</a></p>
   <h4>Next topic</h4>
   <p class="topless"><a href="configuration.html"
@@ -243,7 +243,7 @@
              >next</a> |</li>
         <li class="right" >
-          <a href="overview.html" title="Overview of postman’s architecture"
+          <a href="overview.html" title="Overview of mailjam’s architecture"
              >previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/overview.html
===================================================================
--- docs/src/_build/html/overview.html	(revision 13)
+++ docs/src/_build/html/overview.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Overview of postman’s architecture &mdash; Postman 0.1.0 documentation</title>
+    <title>Overview of mailjam’s architecture &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,7 +26,7 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
     <link rel="next" title="Installation instructions" href="install.html" />
-    <link rel="prev" title="Postman official documentation" href="index.html" /> 
+    <link rel="prev" title="Mailjam official documentation" href="index.html" /> 
   </head>
   <body>
@@ -41,7 +41,7 @@
              accesskey="N">next</a> |</li>
         <li class="right" >
-          <a href="index.html" title="Postman official documentation"
+          <a href="index.html" title="Mailjam official documentation"
              accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -52,12 +52,12 @@
           <div class="body">
             
-  <div class="section" id="overview-of-postman-s-architecture">
-<h1><a class="toc-backref" href="#id1">Overview of postman&#8217;s architecture</a><a class="headerlink" href="#overview-of-postman-s-architecture" title="Permalink to this headline">¶</a></h1>
+  <div class="section" id="overview-of-mailjam-s-architecture">
+<h1><a class="toc-backref" href="#id1">Overview of mailjam&#8217;s architecture</a><a class="headerlink" href="#overview-of-mailjam-s-architecture" title="Permalink to this headline">¶</a></h1>
 <div class="contents topic" id="contents">
 <p class="topic-title first">Contents</p>
 <ul class="simple">
-<li><a class="reference internal" href="#overview-of-postman-s-architecture" id="id1">Overview of postman&#8217;s architecture</a><ul>
+<li><a class="reference internal" href="#overview-of-mailjam-s-architecture" id="id1">Overview of mailjam&#8217;s architecture</a><ul>
 <li><a class="reference internal" href="#introduction" id="id2">Introduction</a></li>
-<li><a class="reference internal" href="#postman-daemon" id="id3">Postman daemon</a></li>
+<li><a class="reference internal" href="#mailjam-daemon" id="id3">Mailjam daemon</a></li>
 <li><a class="reference internal" href="#mta-client" id="id4">MTA client</a></li>
 <li><a class="reference internal" href="#cli-client" id="id5">CLI client</a></li>
@@ -69,13 +69,13 @@
 <div class="section" id="introduction">
 <h2><a class="toc-backref" href="#id2">Introduction</a><a class="headerlink" href="#introduction" title="Permalink to this headline">¶</a></h2>
-<p>Postman has been designed following a <strong>multi-component structure</strong>. There is
+<p>Mailjam has been designed following a <strong>multi-component structure</strong>. There is
 <strong>a daemon</strong> that manage the mailing lists and members information in a storage
 backend and there are <strong>different kinds of clients</strong> (currently, three of them)
 that <strong>interact with the daemon using a XMLRPC link</strong>.</p>
 <p>This is the scheme of the architecture:</p>
-<img alt="Scheme of the architecture behind Postman" class="open-fancybox" src="_images/postman_architecture.png" />
+<img alt="Scheme of the architecture behind Mailjam" class="open-fancybox" src="_images/mailjam_architecture.png" />
 </div>
-<div class="section" id="postman-daemon">
-<span id="overview-postman-daemon"></span><h2><a class="toc-backref" href="#id3">Postman daemon</a><a class="headerlink" href="#postman-daemon" title="Permalink to this headline">¶</a></h2>
+<div class="section" id="mailjam-daemon">
+<span id="overview-mailjam-daemon"></span><h2><a class="toc-backref" href="#id3">Mailjam daemon</a><a class="headerlink" href="#mailjam-daemon" title="Permalink to this headline">¶</a></h2>
 <p>The daemon will perform all the operations regarding the management of the
 mailing lists and members. The daemon will save information of a given
@@ -86,5 +86,5 @@
 </div>
 <div class="section" id="mta-client">
-<span id="overview-postman-mta-client"></span><h2><a class="toc-backref" href="#id4">MTA client</a><a class="headerlink" href="#mta-client" title="Permalink to this headline">¶</a></h2>
+<span id="overview-mailjam-mta-client"></span><h2><a class="toc-backref" href="#id4">MTA client</a><a class="headerlink" href="#mta-client" title="Permalink to this headline">¶</a></h2>
 <p>This client is attached to a given MTA, and is called but the MTA itself when
 emails for a mailing lists are received. The client performs some checks on the
@@ -92,13 +92,13 @@
 </div>
 <div class="section" id="cli-client">
-<span id="overview-postman-cli-client"></span><h2><a class="toc-backref" href="#id5">CLI client</a><a class="headerlink" href="#cli-client" title="Permalink to this headline">¶</a></h2>
+<span id="overview-mailjam-cli-client"></span><h2><a class="toc-backref" href="#id5">CLI client</a><a class="headerlink" href="#cli-client" title="Permalink to this headline">¶</a></h2>
 <p>This is a shell-like interface that can be used to add mailing lists to a given
-Postman server, edit such mailing lists information, add members, etc.</p>
+Mailjam server, edit such mailing lists information, add members, etc.</p>
 </div>
 <div class="section" id="web-client">
-<span id="overview-postman-web-client"></span><h2><a class="toc-backref" href="#id6">Web client</a><a class="headerlink" href="#web-client" title="Permalink to this headline">¶</a></h2>
+<span id="overview-mailjam-web-client"></span><h2><a class="toc-backref" href="#id6">Web client</a><a class="headerlink" href="#web-client" title="Permalink to this headline">¶</a></h2>
 <p>This is a small <em>webapp</em> that can be used to perform the same management
 operations you can achieve using the
-<a class="reference internal" href="#overview-postman-cli-client"><em>CLI client</em></a>.</p>
+<a class="reference internal" href="#overview-mailjam-cli-client"><em>CLI client</em></a>.</p>
 </div>
 </div>
@@ -112,7 +112,7 @@
   <h3><a href="index.html">Table Of Contents</a></h3>
   <ul>
-<li><a class="reference internal" href="#">Overview of postman&#8217;s architecture</a><ul>
+<li><a class="reference internal" href="#">Overview of mailjam&#8217;s architecture</a><ul>
 <li><a class="reference internal" href="#introduction">Introduction</a></li>
-<li><a class="reference internal" href="#postman-daemon">Postman daemon</a></li>
+<li><a class="reference internal" href="#mailjam-daemon">Mailjam daemon</a></li>
 <li><a class="reference internal" href="#mta-client">MTA client</a></li>
 <li><a class="reference internal" href="#cli-client">CLI client</a></li>
@@ -124,5 +124,5 @@
   <h4>Previous topic</h4>
   <p class="topless"><a href="index.html"
-                        title="previous chapter">Postman official documentation</a></p>
+                        title="previous chapter">Mailjam official documentation</a></p>
   <h4>Next topic</h4>
   <p class="topless"><a href="install.html"
@@ -160,7 +160,7 @@
              >next</a> |</li>
         <li class="right" >
-          <a href="index.html" title="Postman official documentation"
+          <a href="index.html" title="Mailjam official documentation"
              >previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/running.html
===================================================================
--- docs/src/_build/html/running.html	(revision 13)
+++ docs/src/_build/html/running.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Running Postman &mdash; Postman 0.1.0 documentation</title>
+    <title>Running Mailjam &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -26,5 +26,5 @@
     <script type="text/javascript" src="_static/underscore.js"></script>
     <script type="text/javascript" src="_static/doctools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
     <link rel="next" title="Some examples" href="examples.html" />
     <link rel="prev" title="Configuration" href="configuration.html" /> 
@@ -43,5 +43,5 @@
           <a href="configuration.html" title="Configuration"
              accesskey="P">previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -52,10 +52,10 @@
           <div class="body">
             
-  <div class="section" id="running-postman">
-<h1><a class="toc-backref" href="#id1">Running Postman</a><a class="headerlink" href="#running-postman" title="Permalink to this headline">¶</a></h1>
+  <div class="section" id="running-mailjam">
+<h1><a class="toc-backref" href="#id1">Running Mailjam</a><a class="headerlink" href="#running-mailjam" title="Permalink to this headline">¶</a></h1>
 <div class="contents topic" id="contents">
 <p class="topic-title first">Contents</p>
 <ul class="simple">
-<li><a class="reference internal" href="#running-postman" id="id1">Running Postman</a></li>
+<li><a class="reference internal" href="#running-mailjam" id="id1">Running Mailjam</a></li>
 </ul>
 </div>
@@ -108,5 +108,5 @@
           <a href="configuration.html" title="Configuration"
              >previous</a> |</li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/search.html
===================================================================
--- docs/src/_build/html/search.html	(revision 13)
+++ docs/src/_build/html/search.html	(revision 16)
@@ -9,5 +9,5 @@
     <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
     
-    <title>Search &mdash; Postman 0.1.0 documentation</title>
+    <title>Search &mdash; Mailjam 0.1.0 documentation</title>
     
     <link rel="stylesheet" href="_static/default.css" type="text/css" />
@@ -27,5 +27,5 @@
     <script type="text/javascript" src="_static/doctools.js"></script>
     <script type="text/javascript" src="_static/searchtools.js"></script>
-    <link rel="top" title="Postman 0.1.0 documentation" href="index.html" />
+    <link rel="top" title="Mailjam 0.1.0 documentation" href="index.html" />
   <script type="text/javascript">
     jQuery(function() { Search.loadIndex("searchindex.js"); });
@@ -41,5 +41,5 @@
           <a href="genindex.html" title="General Index"
              accesskey="I">index</a></li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>  
@@ -89,5 +89,5 @@
           <a href="genindex.html" title="General Index"
              >index</a></li>
-        <li><a href="index.html">Postman 0.1.0 documentation</a> &raquo;</li> 
+        <li><a href="index.html">Mailjam 0.1.0 documentation</a> &raquo;</li> 
       </ul>
     </div>
Index: docs/src/_build/html/searchindex.js
===================================================================
--- docs/src/_build/html/searchindex.js	(revision 13)
+++ docs/src/_build/html/searchindex.js	(revision 16)
@@ -1,1 +1,1 @@
-Search.setIndex({objects:{},terms:{all:[2,6],code:5,identifi:6,edg:5,just:5,softwar:1,gentoo:6,abl:6,offici:[1,5],becaus:6,tcp:2,ssl_kei:6,session:6,through:6,file:[1,6],follow:2,netbsd:6,disk:6,ssl_crt:6,dynam:6,paramet:6,xml:6,content:[0,1,2,3,4,5,6],privat:6,password:6,locat:6,cli:[1,2],listen:[2,6],also:6,configur:[1,6],activ:5,send:6,should:5,add:[2,6],archlinux:6,appli:6,mail:[1,6,2],save:[2,6],local:6,xmlrpc_server:6,bin:5,applic:6,them:2,sourc:[6,5],env:5,xmlrpc:[2,6],get:5,read:[2,6],auto:6,pypi:5,multi:2,tbw:5,repo:5,ssl:6,traffic:6,usual:6,now:6,mailing_list:6,introduct:[1,2],daemon:[1,6,2],like:[2,6],specif:6,edit:2,list:[1,6,2],upload:5,server:[2,6],separ:6,"default":6,achiev:2,exampl:[1,4,5],updat:[2,6],contain:6,small:2,privileg:5,grab:5,secure_socket_lay:6,where:6,manag:[1,2],mean:6,wiki:6,certif:6,www:6,set:[1,6,5],members_db:6,some:[1,4,2],see:6,design:2,download:5,themselv:6,administr:6,port:[2,6],librari:6,hostnam:6,virtualenv:5,index:1,what:2,still:6,postman:[1,3,6,5,2],matter:6,section:6,wikipedia:6,per:6,yet:[6,5],categori:6,delet:2,written:1,version:5,directori:[6,5],"new":6,"public":[6,5],localhost:6,refer:5,hasn:6,run:[1,3,5],insid:5,web:[1,6,2],style:6,here:6,behaviour:6,extens:6,host:5,base:6,repositori:5,ubuntu:6,releas:5,depend:[1,6,5],modifi:6,bleed:5,valu:6,about:[6,5],perform:2,architectur:[1,2],pymotw:6,current:[2,6],doughellmann:6,page:1,configpars:6,etc:[2,6],fals:6,com:6,disabl:6,logfil:6,oper:[2,5],pleas:5,note:[6,5],overview:[1,2],modul:1,within:6,por:6,easy_instal:5,system:[6,5],email:[2,6],instruct:[1,5],alreadi:2,been:[2,6,5],linux:6,instal:[1,6,5],storag:[2,6],your:[6,5],backend:[2,6],kei:6,avail:6,differ:[2,6],from:[2,6,5],log:6,wai:[6,5],interact:2,support:6,regist:6,three:2,messag:6,mercuri:5,attach:2,json:6,interfac:[2,6],usr:6,"var":6,call:2,scheme:2,type:6,until:5,store:6,more:[6,5],shell:[2,5],option:6,python:[1,6,5],copi:[6,5],search:1,warn:[6,5],thi:[1,6,5,2],allow_chpasswd:6,link:2,too:[2,5],webapp:2,given:[2,6],"true":6,those:6,serv:6,wide:5,kind:2,onli:[1,6,5],conf:6,provid:5,setup:[6,5],work:[6,5],onc:5,second:[1,5],structur:2,tell:2,trick:6,record:5,archiv:6,can:[2,6,5],learn:5,exist:6,mta:[1,2],root:5,address:6,unencrypt:6,featur:6,openbsd:6,ini_fil:6,creat:5,process:5,sudo:5,ani:6,doesn:6,compon:2,packag:5,itself:2,right:6,ini:6,have:5,tabl:1,pip:5,incom:2,path:[6,5],check:[2,5],probabl:5,readi:6,encrypt:6,thei:6,want:5,inform:[2,6],receiv:2,travel:6,when:[2,6,5],same:[2,6],reset:6,member:[2,6],how:5,need:5,html:6,anyon:6,rememb:5,test:[1,5],codigo23:5,you:[2,6,5],document:[0,1,5],enabl:6,regard:2,http:[6,5],allow:2,tcsh:5,clone:5,auto_signup:6,most:6,rpc:6,user:6,crt:6,bsd:6,develop:[0,1,5],data:[2,6],debian:6,org:[6,5],csh:5,other:6,bitbucket:5,lists_db:6,off:6,url:5,doc:6,later:6,request:[2,6],inherit:6,fedora:6,registr:6,client:[1,2],environ:5,freebsd:6,indic:1,far:5,first:[1,5],egg:5,order:5,latest:5},objtypes:{},titles:["Developers documentation","Postman official documentation","Overview of postman&#8217;s architecture","Running Postman","Some examples","Installation instructions","Configuration"],objnames:{},filenames:["development","index","overview","running","examples","install","configuration"]})
+Search.setIndex({objects:{},terms:{all:[2,6],code:5,identifi:6,edg:5,just:5,tcsh:5,wikipedia:6,offici:[1,5],becaus:6,tcp:2,ssl_kei:6,session:6,through:6,url:5,ini_fil:6,follow:2,netbsd:6,disk:6,ssl_crt:6,dynam:6,paramet:6,xml:6,categori:6,privat:6,password:6,locat:6,cli:[1,2],how:5,configur:[1,6],activ:5,send:6,should:5,add:[2,6],archlinux:6,overview:[1,2],mail:[1,6,2],tell:2,save:[2,6],local:6,latest:5,bin:5,applic:6,them:2,sourc:[6,5],rememb:5,xmlrpc:[2,6],get:5,read:[2,6],auto:6,pypi:5,kind:2,tbw:5,repo:5,ssl:6,traffic:6,enabl:6,now:6,mailing_list:6,introduct:[1,2],daemon:[1,6,2],like:[2,6],specif:6,edit:2,list:[1,6,2],upload:5,server:[2,6],separ:6,provid:5,achiev:2,have:5,contain:6,small:2,privileg:5,grab:5,secure_socket_lay:6,where:6,manag:[1,2],mean:6,wiki:6,certif:6,www:6,set:[1,6,5],members_db:6,some:[1,4,2],see:6,member:[2,6],design:2,download:5,run:[1,3,5],port:[2,6],librari:6,virtualenv:5,index:1,what:2,still:6,postman:[],record:5,freebsd:6,section:6,abl:6,per:6,yet:[6,5],content:[0,1,2,3,4,5,6],delet:2,written:1,version:5,"new":6,"public":[6,5],localhost:6,refer:5,hasn:6,more:[6,5],themselv:6,insid:5,web:[1,6,2],pleas:5,style:6,here:6,behaviour:6,extens:6,host:5,base:6,repositori:5,ubuntu:6,releas:5,depend:[1,6,5],modifi:6,bleed:5,valu:6,about:[6,5],architectur:[1,2],pymotw:6,current:[2,6],doughellmann:6,page:1,configpars:6,etc:[2,6],fals:6,com:6,disabl:6,user:6,oper:[2,5],softwar:1,client:[1,2],note:[6,5],appli:6,modul:1,within:6,por:6,easy_instal:5,three:2,email:[2,6],instruct:[1,5],alreadi:2,messag:6,right:6,linux:6,instal:[1,6,5],storag:[2,6],your:[6,5],backend:[2,6],kei:6,mercuri:5,differ:[2,6],from:[2,6,5],log:6,wai:[6,5],attach:2,interact:2,support:6,regist:6,system:[6,5],been:[2,6,5],avail:6,mailjam:[1,3,6,5,2],json:6,interfac:[2,6],usr:6,"var":6,call:2,scheme:2,type:6,administr:6,store:6,listen:[2,6],shell:[2,5],option:6,python:[1,6,5],copi:[6,5],search:1,warn:[6,5],allow_chpasswd:6,link:2,too:[2,5],webapp:2,given:[2,6],"true":6,those:6,serv:6,wide:5,multi:2,onli:[1,6,5],"default":6,setup:[6,5],work:[6,5],onc:5,second:[1,5],structur:2,until:5,trick:6,matter:6,itself:2,can:[2,6,5],learn:5,mta:[1,2],root:5,html:6,address:6,unencrypt:6,featur:6,openbsd:6,conf:6,creat:5,process:5,sudo:5,ani:6,doesn:6,compon:2,packag:5,archiv:6,exist:6,ini:6,file:[1,6],tabl:1,pip:5,incom:2,path:[6,5],check:[2,5],probabl:5,readi:6,encrypt:6,thei:6,want:5,inform:[2,6],perform:2,allow:2,travel:6,when:[2,6,5],same:[2,6],reset:6,lists_db:6,also:6,need:5,xmlrpc_server:6,anyon:6,env:5,test:[1,5],environ:5,you:[2,6,5],document:[0,1,5],updat:[2,6],regard:2,http:[6,5],hostnam:6,gentoo:6,clone:5,auto_signup:6,most:6,rpc:6,logfil:6,crt:6,bsd:6,develop:[0,1,5],data:[2,6],debian:6,org:[6,5],csh:5,other:6,bitbucket:5,receiv:2,off:6,directori:[6,5],doc:6,later:6,request:[2,6],inherit:6,fedora:6,registr:6,exampl:[1,4,5],codigo23:5,thi:[1,6,5,2],indic:1,far:5,first:[1,5],egg:5,order:5,usual:6},objtypes:{},titles:["Developers documentation","Mailjam official documentation","Overview of mailjam&#8217;s architecture","Running Mailjam","Some examples","Installation instructions","Configuration"],objnames:{},filenames:["development","index","overview","running","examples","install","configuration"]})
Index: docs/src/conf.py
===================================================================
--- docs/src/conf.py	(revision 13)
+++ docs/src/conf.py	(revision 16)
@@ -1,5 +1,5 @@
 # -*- coding: utf-8 -*-
 #
-# Postman documentation build configuration file, created by
+# Mailjam documentation build configuration file, created by
 # sphinx-quickstart on Sun May 20 12:34:00 2012.
 #
@@ -41,5 +41,5 @@
 
 # General information about the project.
-project = u'Postman'
+project = u'Mailjam'
 copyright = u'2012, Soluciones Informaticas Codigo23 S.L.U.'
 
@@ -165,5 +165,5 @@
 
 # Output file base name for HTML help builder.
-htmlhelp_basename = 'Postmandoc'
+htmlhelp_basename = 'Mailjamdoc'
 
 
@@ -184,5 +184,5 @@
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-  ('index', 'Postman.tex', u'Postman Documentation',
+  ('index', 'Mailjam.tex', u'Mailjam Documentation',
    u'Soluciones Informaticas Codigo23 S.L.U.', 'manual'),
 ]
@@ -214,5 +214,5 @@
 # (source start file, name, description, authors, manual section).
 man_pages = [
-    ('index', 'postman', u'Postman Documentation',
+    ('index', 'mailjam', u'Mailjam Documentation',
      [u'Soluciones Informaticas Codigo23 S.L.U.'], 1)
 ]
@@ -228,6 +228,6 @@
 #  dir menu entry, description, category)
 texinfo_documents = [
-  ('index', 'Postman', u'Postman Documentation',
-   u'Soluciones Informaticas Codigo23 S.L.U.', 'Postman', 'One line description of project.',
+  ('index', 'Mailjam', u'Mailjam Documentation',
+   u'Soluciones Informaticas Codigo23 S.L.U.', 'Mailjam', 'One line description of project.',
    'Miscellaneous'),
 ]
@@ -246,5 +246,5 @@
 
 # Bibliographic Dublin Core info.
-epub_title = u'Postman'
+epub_title = u'Mailjam'
 epub_author = u'Soluciones Informaticas Codigo23 S.L.U.'
 epub_publisher = u'Soluciones Informaticas Codigo23 S.L.U.'
Index: docs/src/configuration.rst
===================================================================
--- docs/src/configuration.rst	(revision 13)
+++ docs/src/configuration.rst	(revision 16)
@@ -6,20 +6,20 @@
 .. _configuration_daemon:
 
-Postman daemon configuration file
+Mailjam daemon configuration file
 ---------------------------------
 
-All the configurations that can be applied to the Postman daemon are registered
-in the **postman.conf** file. That file contains ini-style [1]_ configuration 
+All the configurations that can be applied to the Mailjam daemon are registered
+in the **mailjam.conf** file. That file contains ini-style [1]_ configuration 
 parameters, separated in different *categories*.
 
 .. note::
 
-   The postman.conf file will be installed in different locations depending on
+   The mailjam.conf file will be installed in different locations depending on
    your setup. The usual locations are:
 
-   - */etc/postman.conf* - In most Linux systems (like archlinux, gentoo, 
+   - */etc/mailjam.conf* - In most Linux systems (like archlinux, gentoo, 
      fedora, debian, ubuntu, etc)
 
-   - */usr/local/etc/postman.conf* - In most BSD systems (like FreeBSD, OpenBSD,
+   - */usr/local/etc/mailjam.conf* - In most BSD systems (like FreeBSD, OpenBSD,
      NetBSD, etc)
 
@@ -73,5 +73,5 @@
 *******
 
-Default: ``/usr/local/etc/postman/ssl/postman.key``
+Default: ``/usr/local/etc/mailjam/ssl/mailjam.key``
 
 Path to the ssl key used for encrypted SSL sessions.
@@ -86,5 +86,5 @@
 *******
 
-Default: ``/usr/local/etc/postman/ssl/postman.crt``
+Default: ``/usr/local/etc/mailjam/ssl/mailjam.crt``
 
 Path to the ssl certificate used for encrypted SSL sessions.
@@ -99,5 +99,5 @@
 *******
 
-Default: ``/var/log/postman/xmlrpc_server.log``
+Default: ``/var/log/mailjam/xmlrpc_server.log``
 
 Path to the file where log messages will be saved
@@ -128,5 +128,5 @@
 ****
 
-Default: ``/usr/local/postman/storage``
+Default: ``/usr/local/mailjam/storage``
 
 Path to the directory where the backend will save data.
@@ -137,5 +137,5 @@
 ********
 
-Default: ``/usr/local/postman/storage/mailings.json``
+Default: ``/usr/local/mailjam/storage/mailings.json``
 
 Path to the file where the identifiers of existing mailing lists will be saved.
@@ -165,5 +165,5 @@
 **********
 
-Default: ``/usr/local/postman/storage/members.json``
+Default: ``/usr/local/mailjam/storage/members.json``
 
 Path to the file where the identifiers of existing members will be saved.
@@ -191,5 +191,5 @@
 Default: ``true``
 
-Enables/disables the *archives* feature. When enabled, Postman saves copies of
+Enables/disables the *archives* feature. When enabled, Mailjam saves copies of
 email address into an *archive*, so they can be read later, through a web 
 interface.
@@ -220,5 +220,5 @@
 ****
 
-Default: ``/usr/local/postman/archives``
+Default: ``/usr/local/mailjam/archives``
 
 Path to the directory where the archives will be saved.
@@ -238,5 +238,5 @@
 .. warning::
 
-   This parameters are not currently used in postman, we are still working
+   This parameters are not currently used in mailjam, we are still working
    on per-mailing-list configuration parameters.
 
@@ -265,5 +265,5 @@
 .. warning::
 
-   This parameters are not currently used in postman, we are still working
+   This parameters are not currently used in mailjam, we are still working
    on per-member configuration parameters.
 
Index: docs/src/index.rst
===================================================================
--- docs/src/index.rst	(revision 13)
+++ docs/src/index.rst	(revision 16)
@@ -1,6 +1,6 @@
-Postman official documentation
+Mailjam official documentation
 ==============================
 
-This is the official documentation for Postman_, a mailing list management 
+This is the official documentation for Mailjam_, a mailing list management 
 software written in Python_.
 
@@ -25,4 +25,4 @@
 * :ref:`search`
 
-.. _Postman: https://bitbucket.org/codigo23/postman
+.. _Mailjam: https://bitbucket.org/codigo23/mailjam
 .. _Python: http://python.org
Index: docs/src/install.rst
===================================================================
--- docs/src/install.rst	(revision 13)
+++ docs/src/install.rst	(revision 16)
@@ -9,7 +9,7 @@
 ---------------------------
 
-So far, the only dependency you will need in order to run postman is Python_
+So far, the only dependency you will need in order to run mailjam is Python_
 
-Postman has been tested with python *2.7.x*, but it should work with versions
+Mailjam has been tested with python *2.7.x*, but it should work with versions
 *2.6.x* too.
 
@@ -17,7 +17,7 @@
 more about how to install python.
 
-.. _install_postman:
+.. _install_mailjam:
 
-Second, install Postman
+Second, install Mailjam
 -----------------------
 
@@ -27,12 +27,12 @@
 ++++++++++++++++++++
 
-You can install Postman using pip_::
+You can install Mailjam using pip_::
 
-  pip install -e https://bitbucket.org/codigo23/postman#egg=postman
+  pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam
 
 .. note::
 
-   Postman has not been recorded/uploaded to pypi_ yet, so, in order to install 
-   it using pip you will have to provide the URL for the public Postman repo.
+   Mailjam has not been recorded/uploaded to pypi_ yet, so, in order to install 
+   it using pip you will have to provide the URL for the public Mailjam repo.
 
 .. _install_with_easy_install:
@@ -41,5 +41,5 @@
 +++++++++++++++++++++++++++++
 
-You can not install Postman using easy_install_ yet (until we do record/upload 
+You can not install Mailjam using easy_install_ yet (until we do record/upload 
 it to pypi)
 
@@ -49,5 +49,5 @@
 ++++++++++++++++++++++++++++++
 
-You can install Postman inside a virtualenv_. Just create a virtualenv::
+You can install Mailjam inside a virtualenv_. Just create a virtualenv::
 
   virtualenv /path/to/your/env
@@ -64,7 +64,7 @@
      source /path/to/your/env/bin/activate.csh
 
-And, once the environment has been activated, use pip to install Postman::
+And, once the environment has been activated, use pip to install Mailjam::
 
-  env$ pip install -e https://bitbucket.org/codigo23/postman#egg=postman
+  env$ pip install -e https://bitbucket.org/codigo23/mailjam#egg=mailjam
 
 .. _install_from_sources:
@@ -89,12 +89,12 @@
 ***************
 
-The source code of Postman is hosted in bitbucket_ [1]_. In order to grab
+The source code of Mailjam is hosted in bitbucket_ [1]_. In order to grab
 the latest sources you need Mercurial_.
 
 To get a copy of the sources, just *clone* the repository::
 
-  hg clone https://bitbucket.org/codigo23/postman postman-repo
+  hg clone https://bitbucket.org/codigo23/mailjam mailjam-repo
 
-Then, go inside the *postman-repo* directory and run::
+Then, go inside the *mailjam-repo* directory and run::
 
   python setup.py install
@@ -110,14 +110,14 @@
    This process will work inside a virtualenv_ too.
 
-.. _install_setting_up_postman:
+.. _install_setting_up_mailjam:
 
-Setting up Postman
+Setting up Mailjam
 ------------------
 
 TBW
 
-.. _install_running_postman:
+.. _install_running_mailjam:
 
-Running Postman
+Running Mailjam
 ---------------
 
@@ -140,3 +140,3 @@
 .. _sudo: http://sudo.ws
 
-.. [1] https://bitbucket.org/codigo23/postman
+.. [1] https://bitbucket.org/codigo23/mailjam
Index: docs/src/overview.rst
===================================================================
--- docs/src/overview.rst	(revision 13)
+++ docs/src/overview.rst	(revision 16)
@@ -1,3 +1,3 @@
-Overview of postman's architecture
+Overview of mailjam's architecture
 ==================================
 
@@ -7,5 +7,5 @@
 ------------
 
-Postman has been designed following a **multi-component structure**. There is 
+Mailjam has been designed following a **multi-component structure**. There is 
 **a daemon** that manage the mailing lists and members information in a storage
 backend and there are **different kinds of clients** (currently, three of them)
@@ -14,12 +14,12 @@
 This is the scheme of the architecture:
 
-.. image:: /postman_architecture.png
-   :alt: Scheme of the architecture behind Postman
+.. image:: /mailjam_architecture.png
+   :alt: Scheme of the architecture behind Mailjam
    :class: open_fancybox
 
 
-.. _overview_postman_daemon:
+.. _overview_mailjam_daemon:
 
-Postman daemon
+Mailjam daemon
 --------------
 
@@ -32,5 +32,5 @@
 to add/update/delete data from the backend.
 
-.. _overview_postman_mta_client:
+.. _overview_mailjam_mta_client:
 
 MTA client
@@ -41,5 +41,5 @@
 backend to tell the MTA what it has to do with the incoming emails.
 
-.. _overview_postman_cli_client:
+.. _overview_mailjam_cli_client:
 
 CLI client
@@ -47,7 +47,7 @@
 
 This is a shell-like interface that can be used to add mailing lists to a given
-Postman server, edit such mailing lists information, add members, etc. 
+Mailjam server, edit such mailing lists information, add members, etc. 
 
-.. _overview_postman_web_client:
+.. _overview_mailjam_web_client:
 
 Web client
@@ -56,3 +56,3 @@
 This is a small *webapp* that can be used to perform the same management 
 operations you can achieve using the 
-:ref:`CLI client<overview_postman_cli_client>`.
+:ref:`CLI client<overview_mailjam_cli_client>`.
Index: docs/src/running.rst
===================================================================
--- docs/src/running.rst	(revision 13)
+++ docs/src/running.rst	(revision 16)
@@ -1,3 +1,3 @@
-Running Postman
+Running Mailjam
 ===============
 
Index: mailjam/__init__.py
===================================================================
--- mailjam/__init__.py	(revision 16)
+++ mailjam/__init__.py	(revision 16)
@@ -0,0 +1,4 @@
+# -*- coding: utf-8 -*-
+
+from mailjam.models import Member, MailingList
+from mailjam.storage import JsonStorage
Index: mailjam/archives/README
===================================================================
--- mailjam/archives/README	(revision 16)
+++ mailjam/archives/README	(revision 16)
@@ -0,0 +1,1 @@
+Default archives location
Index: mailjam/config.py
===================================================================
--- mailjam/config.py	(revision 16)
+++ mailjam/config.py	(revision 16)
@@ -0,0 +1,105 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - config.py
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+import os
+from ConfigParser import SafeConfigParser
+
+class DaemonConfig():
+    def __init__(self, configfile=None):
+        self.configfile = configfile
+        self.default_paths = ['/usr/local/etc/mailjam', '/usr/local/etc',
+                              '/etc/mailjam', '/etc',
+                              os.path.join(os.path.dirname(__file__),'../conf')]
+        self.config = {}
+
+    @property
+    def default_filename(self):
+        """
+        Method to get the default configuration filename. It is a method instead
+        of an attribute for easier subclassing
+        """
+        return 'mailjam.conf'
+
+    @property
+    def sections(self):
+        """
+        Method to get the list of available sections in the configuration file.
+        It is a method instead of an attribute for easier subclassing.
+
+        FIXME: Perhaps it would be better to dinamically get the list of
+        sections from the configuration file itself.
+        """
+        return ['xmlrpc_server', 'storage', 'archive',
+                'mailing_lists', 'members']
+    
+    def validate_configfile(self):        
+        if self.configfile:
+            if not os.path.exists(self.configfile):
+                # the file does not exist, so we override it with None,
+                # allowing the next few lines to search for a valid
+                # config file on the usual places
+                self.configfile = None
+            
+        if not self.configfile:
+            for path in self.default_paths:
+                full_path = os.path.join(path, self.default_filename)
+                if os.path.exists(full_path):
+                    self.configfile = full_path
+                    return full_path
+                
+        # if we reach here, self.configfile will be still None, no valid
+        # config files were found, and so we raise an exception
+        raise IOError('ERROR - Can not find ' + self.default_filename + \
+                      ' in your environment')
+
+    def load(self):
+        if not self.configfile:
+            self.validate_configfile()
+        parser = SafeConfigParser()
+        parser.read(self.configfile)
+        for section in self.sections:
+            self.config[section] = {}
+            for name, value in parser.items(section):
+                self.config[section][name] = value
+        return self.config        
+
+    def get_section_parameters(self, section):
+        if section not in self.sections:
+            raise IndexError('ERROR - ' + section + \
+                             ' is not one of the available sections: ' + \
+                             ', '.join(self.sections))
+        if section not in self.config.keys():
+            # perhaps the config hasn't been loaded yet
+            self.load()
+
+        return self.config[section]
+
+class MTAClientConfig(DaemonConfig):
+    @property
+    def default_filename(self):
+        return 'mailjam-mta.conf'
+
+    @property
+    def sections(self):
+        return ['server', 'archive']
+
+
+def get_config_parameters(section=None, configfile=None):
+    """
+    This function is kept here for backwards compatibility.
+    By default all the daemon code will use this function to get
+    configuration parameters from the default configuration file.
+    """
+    config = DaemonConfig(configfile)
+    return config.get_section_parameters(section)
+
+    
Index: mailjam/daemon.py
===================================================================
--- mailjam/daemon.py	(revision 16)
+++ mailjam/daemon.py	(revision 16)
@@ -0,0 +1,245 @@
+# -*- coding: utf-8 -*-
+
+import os, inspect, logging
+from SimpleXMLRPCServer import SimpleXMLRPCServer, list_public_methods
+
+from mailjam import config
+from mailjam.models import Member, MailingList
+from mailjam.storage import JsonStorage as Storage
+
+
+class Mailjam():
+
+    def __init__(self, configfile=None):
+        self.storage_config = config.get_config_parameters('storage',
+                                                           configfile)
+        self.archive_config = config.get_config_parameters('archive',
+                                                           configfile)
+
+        # lists were the currently managed mailing lists information is going
+        # to be saved
+        self.mailings = {}
+        self.mailings_addresses = []
+        
+        # the files were internal information (like active mailing lists,
+        # members, etc) is saved
+        self.dbs = {'mailings': Storage(self.storage_config['lists_db']),
+                    'members': Storage(self.storage_config['members_db'])}
+
+    def save(self):
+        """
+        Save all the current managed data to disk
+        """
+        if self.mailings:
+            # Save the config file from where we can reload information about
+            # the mailing lists managed by this mailjam instance
+            self.dbs['mailings'].write(self.mailings_addresses)
+            # Save each mailing list data into its separated persistence file
+            for m in self.mailings.keys():            
+                self.mailings[m].save()
+            return True
+        return False
+
+    def load(self):
+        """
+        Load all data from the storage files
+        """
+        if self.dbs['mailings'].exists():
+            # load the list of managed mailing lists
+            # FIXME: This is quite naive, we do not perform any check here after
+            # loading the data from the json file, which can be modified by
+            # untrustred users.
+            self.mailings_addresses = self.dbs['mailings'].read()
+
+            # now load all the mailing objects:
+            for address in self.mailings_addresses:
+                mailing = MailingList(address, address)
+                mailing.load()
+                self.mailings[address] = mailing                
+            return True
+        return False
+
+    def clear(self):
+        """
+        Delete all stored data from disk (useful for testing).
+        DANGER: Calling this method will remove all data from disk, leaving the
+        mailjam instance with no persistence data, if the mailjam process die,
+        before another .save() call is made, all data will be lost.
+        """
+        if self.dbs['mailings'].exists():
+            # We do not delete each mailing list file, but only the file
+            # containing the list of existing mailing lists
+            self.dbs['mailings'].delete()
+            return True
+        return False
+
+    def add_mailing_list(self, info={}):
+        """
+        Add a new mailing list to this mailjam instance. expects one parameter,
+        info, which is a dictionary that should contain, at least, the
+        following keys:
+
+         - name: (string) the name we will give to the list
+         - address: (string) the email address of the list
+         - members: (list) a list of email adddress of the list members
+         
+        """
+        if not isinstance(info, dict):
+            raise TypeError(info, ' is not a valid dictionary')
+
+        if 'name' not in info.keys() or \
+           'address' not in info.keys() or \
+           'members' not in info.keys() or \
+           'configfile' not in info.keys():
+            raise ValueError(info, ' does not seem to be a valid configuration')
+        
+        if info['address'] in self.mailings_addresses:
+            raise IndexError(info['address'],
+                             ' has been already added to mailjam')
+
+        mailing = MailingList(info['name'], info['address'],
+                              info['members'], info['configfile'])
+        self.mailings[mailing.address] = mailing
+        self.mailings_addresses.append(mailing.address)
+        # After adding new mailings, save them to disk
+        self.save()
+        return True
+        
+    def add_mailing_member(self, member_addr=None, list_addr=None):
+        """
+        Add a new member for the mailing list represented by list_addr (a string
+        containing the email address of any mailing list managed by this mailjam
+        instance). member_addr is a string representing the email address of the
+        new member
+        """
+
+        if not member_addr:
+            raise ValueError(member_addr, 'missing member address')
+
+        if not list_addr:
+            raise ValueError(list_addr, 'missing list address')
+
+        if list_addr not in self.mailings_addresses:
+            # FIXME: Perhaps we should add it, perhaps not (mispelled address?)
+            raise IndexError(list_addr, ' is not a valid mailing list')
+
+        added = self.mailings[list_addr].add_member_by_address(member_addr)
+        if added:
+            self.save()
+        return added
+
+
+class MailjamXMLRPC():
+    """
+    This class is a wrapper we will use to limit the methods that will be
+    published through the XMLRPC link. Only the methods from this class
+    will be available through that link.
+
+    As we use dotted names to separate xmlrpc-exported methods into different
+    namespaces, this class contains nothing, it will be used only for
+    method-registering purposes. The MailingListXMLRPC and MemberXMLRPC classes
+    contain the actual methods that are published.
+
+    More information on this approach here:
+
+    http://www.doughellmann.com/PyMOTW/SimpleXMLRPCServer/#exposing-methods-of-objects
+    """
+
+    def _listMethods(self):
+        public_methods = []
+        public_methods += ['lists.'+i for i in dir(MailingListXMLRPC) if '_' not in i]
+        public_methods += ['members.'+i for i in dir(MemberXMLRPC) if '_' not in i]
+        return public_methods
+
+    def _methodHelp(self, method):
+        f = getattr(self, method)
+        return inspect.getdoc(f)
+
+
+class MailingListXMLRPC():
+    def __init__(self):
+        self.mailjam = Mailjam()
+        self.mailjam.load()
+    def add(self, info={}):
+        self.mailjam.add_mailing_list(info)
+    def addresses(self):
+        return self.mailjam.mailings_addresses    
+
+
+class MemberXMLRPC():
+    def __init__(self):
+        self.mailjam = Mailjam()
+        self.mailjam.load()
+    def add(self, member_addr=None, list_addr=None):
+        self.mailjam.add_mailing_member(member_addr, list_addr)
+    def list(self, mailing):
+        if mailing in self.mailjam.mailings_addresses:
+            return self.mailjam.mailings[mailing].members_addresses()
+
+
+class MailjamDaemon():
+    def __init__(self, configfile=None):
+        self.config = config.get_config_parameters('xmlrpc_server', configfile)
+
+        # FIXME: These should be loaded from a config file
+        self.address = self.config.get('address', 'localhost')
+        self.port = int(self.config.get('port', 9876))
+        self.logfile = self.config.get('logfile',
+                                       os.path.join(os.path.dirname(__file__),
+                                                    'server.log'))
+        logging.basicConfig(filename=self.logfile, level=logging.DEBUG)
+        self.server = None
+        self.ready_to_serve = False
+        
+    def create_server(self):
+        """
+        If there is no server initialized in self.server, create an instance
+        of SimpleXMLRPCServer in that attribute. If there is already a server
+        initialized there, simply return True
+        """           
+        if not self.server:
+            msg = 'Creating XMLRPC server object on {}:{}'.format(self.address,
+                                                                  self.port)
+            logging.info(msg)
+            self.server = SimpleXMLRPCServer((self.address, self.port),
+                                             allow_none=True,
+                                             logRequests=False)
+            self.server.register_introspection_functions()
+        return True
+
+    def add_methods(self):
+        """
+        Check if there is an initialized server (initialize it if there is none)
+        and then register all the Mailjam public methods to be served through
+        the xml-rpc link
+
+        Once the methods are registered set self.ready_to_serve to True        
+        """
+        if not self.server:
+            # ensure there is an XMLRPC server initialized
+            self.create_server()
+        msg = 'Registering public methods'
+        logging.info(msg)
+        root = MailjamXMLRPC()
+        root.lists = MailingListXMLRPC()
+        root.members = MemberXMLRPC()
+        self.server.register_instance(root, allow_dotted_names=True)
+        self.ready_to_serve = True
+        return self.ready_to_serve
+            
+    def run(self):
+        """
+        Run the xmlrpc daemon. If self.ready_to_serve is False, call
+        self.add_methods, which will initialize the server and will register all
+        the public methods into that server
+        """
+        if not self.ready_to_serve:
+            self.add_methods()
+        msg = 'Starting XMLRPC server on {}:{}'.format(self.address,
+                                                       self.port)
+        logging.info(msg)
+        try:
+            self.server.serve_forever()
+        except KeyboardInterrupt:
+            msg = 'Stopping server'
+            logging.info(msg)
Index: mailjam/models.py
===================================================================
--- mailjam/models.py	(revision 16)
+++ mailjam/models.py	(revision 16)
@@ -0,0 +1,129 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - models.py
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+import os
+from tools import validate_email_address
+from storage import JsonStorage as Storage
+import config
+
+class Member():
+
+    """
+    Class that defines a mailing list member
+    """
+
+    def __init__(self, address):
+        self.address = self._validate_address(address)
+        
+    def __repr__(self):
+        return "<Member '%s'>" % self.address
+
+    def __str__(self):
+        return self.address
+
+    def _validate_address(self, address):
+        if not validate_email_address(address):
+            raise ValueError(address, ' is not a valid email address')
+        return address
+
+
+class MailingList():
+
+    """
+    Class that defines a mailing list
+    """
+
+    def __init__(self, name, address, members={}, configfile=None):
+        self.configfile = configfile
+        self.storage_config = config.get_config_parameters('storage',
+                                                           configfile)
+        self.archive_config = config.get_config_parameters('archive',
+                                                           configfile)
+        self.mailing_config = config.get_config_parameters('mailing_lists',
+                                                           configfile)
+        self.name = name
+        self.address = address
+        self.members = members
+        
+    def __repr__(self):
+        return "<MailingList '%s'>" % self.address
+
+    def __str__(self):
+        return self.address
+        
+    def _validate_member_object(self, member=None):
+        if not isinstance(member, Member):
+            raise TypeError(member, ' is not a valid Member instance')
+        return member
+
+    def _validate_member(self, member=None):
+        member = self._validate_member_object(member)
+        return member.address in self.members_addresses()
+
+    def _validate_member_by_address(self, address=None):
+        if not validate_email_address(address):
+            raise ValueError(address, ' is not a valid email address')
+        return address in self.members_addresses()
+
+    @property
+    def storage(self):
+        return Storage(os.path.join(self.storage_config['path'], self.address))
+
+    @property
+    def archive(self):
+        return Storage(os.path.join(self.archive_config['path'], self.address))
+    
+    def members_addresses(self):
+        return self.members.keys()
+
+    def add_member(self, member):
+        member = self._validate_member_object(member)
+        if self._validate_member(member):
+            return False
+        self.members[member.address] = member
+        return True
+
+    def add_member_by_address(self, address=None):
+        if self._validate_member_by_address(address):
+            return False
+        member = Member(address)
+        self.members[address] = member
+        return True
+                
+    def delete_member(self, member=None):
+        member = self._validate_member_object(member)
+        if not self._validate_member(member):
+            return False
+        del self.members[member.address]
+        return True
+
+    def info(self):
+        """
+        Returns a dict we can use to add this mailing list to a mailjam
+        instance
+        """
+        # FIXME: This code could be replaced with something that
+        # automagically generates the dict from the instance attributes
+        return {'name': self.name, 'address': self.address,
+                'members': self.members, 'configfile': self.configfile}
+
+    def load(self):
+        if self.storage.exists():
+            data = self.storage.read()
+            self.name = data.name
+            self.address = data.address
+            self.members = data.members
+            return True
+        return False
+    
+    def save(self):
+        self.storage.write(self)
Index: mailjam/mta.py
===================================================================
--- mailjam/mta.py	(revision 16)
+++ mailjam/mta.py	(revision 16)
@@ -0,0 +1,113 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - mta.py
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+import os, sys, email, smtplib, xmlrpclib
+from datetime import datetime
+from mailjam.models import MailingList
+from mailjam.config import MTAClientConfig
+from mailjam.tools import validate_email_address
+
+class MTAClient():
+    
+    def __init__(self, address=None, configfile=None):
+        if not validate_email_address(address):
+            raise ValueError(address, ' is not a valid email address')
+
+        mta_config = MTAClientConfig()
+        mta_config.load()
+        self.config = mta_config.config
+        self.rpc = xmlrpclib.ServerProxy(self.config['server']['uri'])
+        self.address = self._validate_address(address)
+        self.suscriptors = self.rpc.members.list(address)
+        self.reply_to = self.address
+        self.raw_email = None
+        self.queue = []
+
+    def _validate_archive_path(self):
+        """
+        Validate that the archive path exists. If not, try to create it
+        """
+        if not os.path.exists(self.config['archive']['path']):
+            # FIXME: This will raise an IOError if the user has no
+            # privileges to create the directory, perhaps we should catch
+            # that and show an error instead
+            os.makedirs(self.config['archive']['path'])
+        return True        
+        
+    def _validate_address(self, address=None):
+        """
+        The address provided by the user will be valid only if it is a
+        valid email address and if it is the email address of an already
+        existing mailing list
+        """
+        if not validate_email_address(address):
+            raise ValueError(address, ' is not a valid email address')
+        if not address in self.rpc.lists.addresses():
+            raise ValueError(address,
+                             ' is not the address of any existing mailing list')
+        # If it is valid, return it
+        return address
+    
+    def get_raw_email(self, raw_email=None):
+        """
+        get the raw data containing email information. If raw_email is None,
+        try to get the data from stdin
+        """
+        if not raw_email:
+            try:
+                self.raw_email = sys.stdin.read()
+            except:
+                raise IOError('Can not get a valid email from stdin')
+        else:
+            self.raw_email = raw_email
+        # FIXME: We should perform some checks on the raw data, ensuring
+        # it is a valid email text
+        return self.raw_email
+
+    def save_raw_email(self):
+        if not self.raw_email:
+            # FIXME: perhaps a while loop here, with some maximum recursion
+            # check, would be nice here
+            self.get_raw_email()
+        # Check the path to the archive exists
+        self._validate_archive_path()
+        filename = os.path.join(self.config['archive']['path'],
+                                datetime.today().strftime('%Y%d%m%H%M%S%f'))
+        tmpfile = file(filename, 'w')
+        tmpfile.write(self.raw_email)
+        tmpfile.close()
+        self.queue.append(filename)
+
+    def send_email(self):
+        """
+        Send emails from the queue, if there is any
+        """
+        if self.queue:
+            next_email = self.queue.pop()
+            email_file = file(next_email, 'r')
+            email_data = email.message_from_file(email_file)
+            email_file.close()
+            email_data['Reply-to'] = self.reply_to
+            print 'SENDING EMAIL:'
+            print email_data
+            #smtp_conn = smtplib.SMTP()
+            #smtp_conn.connect()
+            #smtp_conn.sendmail(email_data['From'], self.suscriptors,
+            #                   email_data.as_string())
+            #smtp_conn.close()
+            # FIXME: enable tmp data removal here:
+            # if not self.config['archive']['persistent']:
+            #     REMOVE THE FILE FROM DISK
+
+    def run(self):
+        self.save_raw_email()
+        self.send_email()
Index: mailjam/storage.py
===================================================================
--- mailjam/storage.py	(revision 16)
+++ mailjam/storage.py	(revision 16)
@@ -0,0 +1,100 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - storage.py
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+import os, errno, json
+
+
+class JsonStorage():
+
+    """
+    Json-based storage. 
+    """
+
+    def __init__(self, path='storage.json'):
+        if os.path.isdir(path):
+            raise IOError(path, ' is a directory, exiting')
+        self.path = path
+
+    def exists(self):
+        return os.path.exists(self.path)    
+
+    def create(self):
+        """
+        Ensure all the subdirectories in the path to the storage file
+        exist
+        """
+        try:
+            os.makedirs(os.path.dirname(self.path))
+        except OSError, e:
+            # If the dir already exists do not complain, if it is
+            # any other error, raise the exception
+            if e.errno != errno.EEXIST:
+                raise
+    
+    def jsonize(self, obj):
+        """
+        Convert objects to a dictionary of their representation
+        Based on the exmplaes from Doyg Hellmann:
+        http://www.doughellmann.com/PyMOTW/json/#working-with-your-own-types
+        """
+        jobj = { '__class__':obj.__class__.__name__, 
+                 '__module__':obj.__module__,
+                 }
+        jobj.update(obj.__dict__)
+        return jobj
+
+    def dejsonize(self, jobj):
+        """
+        Convert some data that has been "jsonized" to the original
+        python object. Again, based on the examples from Doug Hellmann
+        """
+        if '__class__' in jobj:
+            class_name = jobj.pop('__class__')
+            module_name = jobj.pop('__module__')
+            module = __import__(module_name)
+            class_ = getattr(module, class_name)
+            args = dict((key.encode('ascii'), value) \
+                        for key, value in jobj.items())
+            return class_(**args)
+        return jobj
+        
+    def write(self, data):
+        if not self.exists():
+            # ensure the path to the storage file exists
+            self.create()
+        with open(self.path, 'w') as storage:
+            json.dump(data, storage, sort_keys=True, indent=4,
+                      default=self.jsonize)
+            return True 
+        return False 
+
+    def read(self):        
+        with open(self.path, 'r') as storage:
+            try:
+                data = json.load(storage,object_hook=self.dejsonize)
+            except ValueError:
+                # if no json data could be imported, the file could be
+                # damaged or perhaps it does not containg json-encoded
+                # data, simply return an empty string
+                #
+                # FIXME: we should notify the user about the problem
+                return ''
+        return data
+
+    def delete(self):
+        """
+        Remove the storage file
+        """
+        if self.exists():
+            os.remove(self.path)
+            return True
+        return False
Index: mailjam/storage/README
===================================================================
--- mailjam/storage/README	(revision 16)
+++ mailjam/storage/README	(revision 16)
@@ -0,0 +1,1 @@
+Default storage location
Index: mailjam/storage/mailings/README
===================================================================
--- mailjam/storage/mailings/README	(revision 16)
+++ mailjam/storage/mailings/README	(revision 16)
@@ -0,0 +1,1 @@
+Default mailing list storage location
Index: mailjam/tests/__init__.py
===================================================================
--- mailjam/tests/__init__.py	(revision 16)
+++ mailjam/tests/__init__.py	(revision 16)
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - tests module
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+from models import *
+# from mta import *
+from daemon import *
Index: mailjam/tests/daemon.py
===================================================================
--- mailjam/tests/daemon.py	(revision 16)
+++ mailjam/tests/daemon.py	(revision 16)
@@ -0,0 +1,202 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - daemon.py
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+import os, multiprocessing, xmlrpclib, time
+from SimpleXMLRPCServer import SimpleXMLRPCServer
+from unittest import TestCase
+
+from mailjam.daemon import Mailjam, MailjamXMLRPC, MailjamDaemon
+from mailjam.models import Member, MailingList
+from mailjam.storage import JsonStorage as Storage
+
+
+class TestMailjam(TestCase):
+    """
+    mailjam.daemon.Mailjam tests.
+
+    Remember to call the .clear() method of mailjam after each test, so
+    the temp storage files are deleted
+    """
+    def setUp(self):
+        self.configfile = os.path.join(os.path.dirname(__file__), 'mailjam.conf')
+        self.mailing_list = MailingList('test_list', 'test_list@example.com',
+                                        members={}, configfile=self.configfile)
+        self.member =  Member('test@example.com')
+
+    def test___init__(self):
+        mailjam = Mailjam(configfile=self.configfile)
+        self.assertIsInstance(mailjam, Mailjam)
+        self.assertEqual(mailjam.mailings, {})
+        self.assertEqual(mailjam.mailings_addresses, [])
+        self.assertIsInstance(mailjam.dbs, dict)
+        self.assertTrue('mailings' in mailjam.dbs.keys())
+        self.assertTrue('members' in mailjam.dbs.keys())
+        self.assertIsInstance(mailjam.dbs['mailings'], Storage)
+        self.assertIsInstance(mailjam.dbs['members'], Storage)
+
+    def test_save(self):
+        mailjam = Mailjam(configfile=self.configfile)
+        self.assertFalse(mailjam.save())
+        mailjam.add_mailing_list(self.mailing_list.info())
+        self.assertTrue(mailjam.save())
+        # FIXME: We have to test here that the generated json file
+        # contains the data it should contain
+
+        # Clear the files created by the tests
+        mailjam.clear()
+
+    def test_load(self):
+        mailjam = Mailjam(configfile=self.configfile)
+        self.assertFalse(mailjam.mailings)
+        self.assertFalse(mailjam.mailings_addresses)
+        self.assertFalse(mailjam.load())
+        mailjam.add_mailing_list(self.mailing_list.info())
+        self.assertTrue(mailjam.load())
+
+        # Check that another mailjam instance is able to load the saved data
+        mailjam_load = Mailjam(configfile=self.configfile)
+        self.assertFalse(mailjam_load.mailings)
+        self.assertFalse(mailjam_load.mailings_addresses)
+        mailjam_load.load()
+        self.assertTrue(mailjam_load.mailings)
+        self.assertIsInstance(mailjam_load.mailings, dict)
+        self.assertTrue(mailjam_load.mailings_addresses)
+        self.assertIsInstance(mailjam_load.mailings_addresses, list)        
+
+        # Clear the files created by the tests
+        mailjam.clear()
+
+    def test_clear(self):
+        mailjam = Mailjam(configfile=self.configfile)
+        self.assertFalse(mailjam.clear())
+        mailjam.add_mailing_list(self.mailing_list.info())
+        self.assertTrue(mailjam.clear())
+
+    def test_add_mailing_list(self):
+        mailjam = Mailjam(configfile=self.configfile)
+        with self.assertRaises(TypeError):
+            # test improper info values
+            mailjam.add_mailing_list(['a list', 'is an', 'invalid parameter'])
+            mailjam.add_mailing_list(self.mailing_list)
+        with self.assertRaises(ValueError):
+            #test incomplete/missing info values
+            mailjam.add_mailing_list()
+            mailjam.add_mailing_list({'name': 'missing info'})
+            mailjam.add_mailing_list({'address': 'missing info'})
+            mailjam.add_mailing_list({'name': 'missing info',
+                                      'address': 'missing info'})
+        # test mailing lists can be added
+        self.assertTrue(mailjam.add_mailing_list(self.mailing_list.info()))
+        self.assertTrue(mailjam.mailings)
+        self.assertIsInstance(mailjam.mailings, dict)
+        self.assertTrue(mailjam.mailings_addresses)
+        self.assertIsInstance(mailjam.mailings_addresses, list)
+        with self.assertRaises(IndexError):
+            # test what happens when the mailing has been already added
+            mailjam.add_mailing_list(self.mailing_list.info())
+
+        # Clear the files created by the tests
+        mailjam.clear()
+
+    def test_add_mailing_member(self):
+        mailjam = Mailjam(configfile=self.configfile)
+        mailjam.add_mailing_list(self.mailing_list.info())
+        with self.assertRaises(ValueError):
+            # test what happens if we call the method without proper
+            # parameters
+            mailjam.add_mailing_member()
+            mailjam.add_mailing_member(None, None)
+            mailjam.add_mailing_member(None, 'test_list@example.net')
+            mailjam.add_mailing_member('test@example.net', None)
+            mailjam.add_mailing_member('test@example', 'test_list@example.net')
+        with self.assertRaises(IndexError):
+            # test if we try to add a member to a non-existing mailing list
+            mailjam.add_mailing_member('test@example.net',
+                                       'test_list_b@example.net')
+        # Test adding a member
+        self.assertTrue(mailjam.add_mailing_member('test@example.net',
+                                                   self.mailing_list.address))
+        # Test trying to re-add that user
+        self.assertFalse(mailjam.add_mailing_member('test@example.net',
+                                                    self.mailing_list.address))
+
+        # Clear the files created by the tests
+        mailjam.clear()
+
+
+class TestMailjamDaemon(TestCase):
+    """
+    mailjam.daemon.MailjamDaemon tests.
+
+    Remember to call the .clear() method of mailjam after each test, so
+    the temp storage files are deleted
+    """
+    def setUp(self):
+        self.configfile = os.path.join(os.path.dirname(__file__),
+                                       'mailjam.conf')
+        self.mailing_list = MailingList('test_xmlrpc',
+                                        'test_xmlrpc@example.com', members={},
+                                        configfile=self.configfile)
+        self.member =  Member('test@example.com')
+
+    def test___init__(self):
+        daemon = MailjamDaemon(self.configfile)
+        self.assertIsInstance(daemon, MailjamDaemon)
+        self.assertFalse(daemon.ready_to_serve)
+        # FIXME: More tests should be added here once the configuration
+        # file feature is added        
+
+    def test_create_server(self):
+        daemon = MailjamDaemon(self.configfile)
+        daemon.port = 9001
+        self.assertTrue(daemon.create_server())
+        self.assertIsInstance(daemon.server, SimpleXMLRPCServer)
+        self.assertFalse(daemon.ready_to_serve)
+        
+    def test_add_methods(self):
+        daemon = MailjamDaemon(self.configfile)
+        daemon.port = 9002
+        self.assertTrue(daemon.add_methods())
+        self.assertTrue(daemon.ready_to_serve)
+
+        daemon = MailjamDaemon(self.configfile)
+        daemon.port = 9003        
+        daemon.create_server()
+        self.assertTrue(daemon.add_methods())
+        self.assertTrue(daemon.ready_to_serve)
+        
+    def test_run(self):
+        daemon = MailjamDaemon(self.configfile)
+        daemon.port = 9004
+        # start the daemon in another process, so we can start communicating
+        # with itjobs = []
+        p = multiprocessing.Process(target=daemon.run)
+        p.start()
+
+        # Add a delay here to allow the server to be fully started before
+        # starting to send requests from the client
+        time.sleep(2)
+        
+        # FIXME: Hardcoded url here, should be picked from a config file        
+        client = xmlrpclib.ServerProxy('http://localhost:9004')
+
+        # Check that we can perform an XMLRPC call and that the list of
+        # available public methods contains the list of methods we have
+        # defined in our base XMLRPC class
+        set_class_methods = set(MailjamXMLRPC()._listMethods())
+        set_xmlrpc_methods = set(client.system.listMethods())
+        self.assertTrue(set_class_methods.issubset(set_xmlrpc_methods))
+        
+        # Stop the server
+        p.terminate()
+        
+        
Index: mailjam/tests/mailjam-mta.conf
===================================================================
--- mailjam/tests/mailjam-mta.conf	(revision 16)
+++ mailjam/tests/mailjam-mta.conf	(revision 16)
@@ -0,0 +1,13 @@
+#
+# mailjam-mta.conf - Mailjam MTA client configuration file
+#
+
+[server]
+address = localhost
+port = 9100 # this port is hardcoded in tests/mta.py
+uri = http://%(address)s:%(port)s
+ssl = false
+
+[archive]
+persistent = true
+path = /tmp/mailjam-tests/mta/archive
Index: mailjam/tests/mailjam.conf
===================================================================
--- mailjam/tests/mailjam.conf	(revision 16)
+++ mailjam/tests/mailjam.conf	(revision 16)
@@ -0,0 +1,31 @@
+#
+# mailjam.conf - Mailjam configuration file
+#
+# IMPORTANT: This config file should be used only
+# for testing purposes
+
+[xmlrpc_server]
+address = localhost
+port = 9876
+ssl = false
+ssl_key = /usr/local/etc/mailjam/ssl/mailjam.key
+ssl_crt = /usr/local/etc/mailjam/ssl/mailjam.crt
+logfile = /tmp/mailjam-tests/xmlrpc_server.log
+
+[storage]
+backend = json
+path = /tmp/mailjam-tests/storage
+lists_db = %(path)s/mailings.%(backend)s
+members_db = %(path)s/members.%(backend)s
+
+[archive]
+enabled = true
+backend = json
+path = /tmp/mailjam-tests/archives
+
+[mailing_lists]
+private = true
+
+[members]
+auto_signup = false
+allow_chpasswd = false
Index: mailjam/tests/models.py
===================================================================
--- mailjam/tests/models.py	(revision 16)
+++ mailjam/tests/models.py	(revision 16)
@@ -0,0 +1,98 @@
+# -*- coding: utf-8 -*-
+
+import os
+from unittest import TestCase
+from mailjam.models import Member, MailingList
+
+
+class TestMember(TestCase):
+    def setUp(self):
+        self.member = Member('test@example.com')
+
+    def test__validate_address(self):
+        self.assertEqual(self.member._validate_address(self.member.address),
+                         self.member.address)
+        with self.assertRaises(ValueError):
+            self.member._validate_address('notavalidemail')
+
+    
+class TestMailingList(TestCase):
+    def setUp(self):
+        configfile = os.path.join(os.path.dirname(__file__), 'mailjam.conf')
+        self.mailing_list = MailingList('test_list', 'test_list@example.com',
+                                        members={}, configfile=configfile)
+        self.member =  Member('test@example.com')
+
+    def test__validate_member_object(self):
+        self.assertEqual(self.mailing_list._validate_member_object(self.member),
+                         self.member)
+        with self.assertRaises(TypeError):
+            self.mailing_list._validate_member_object(None)
+            self.mailing_list._validate_member_object('Not a member object')
+            self.mailing_list._validate_member_object(self.mailing_list)
+
+    def test__validate_member(self):
+        # At first the member object is not a member of the list
+        self.assertFalse(self.mailing_list._validate_member(self.member))
+        self.mailing_list.add_member(self.member)
+        self.assertTrue(self.mailing_list._validate_member(self.member))
+        with self.assertRaises(TypeError):
+            self.mailing_list._validate_member(None)
+            self.mailing_list._validate_member('Not a member object')
+            self.mailing_list._validate_member(self.mailing_list)
+        
+    def test__validate_member_by_address(self):
+        self.assertFalse(self.mailing_list._validate_member_by_address(self.member.address))
+        self.mailing_list.add_member(self.member)
+        self.assertTrue(self.mailing_list._validate_member_by_address(self.member.address))
+        with self.assertRaises(ValueError):
+            self.mailing_list._validate_member_by_address(self.member)
+            self.mailing_list._validate_member_by_address(None)            
+            self.mailing_list._validate_member_by_address('Not a member object')
+            self.mailing_list._validate_member_by_address(self.mailing_list)
+
+    def test_members_addresses(self):
+        self.assertEqual(self.mailing_list.members_addresses(), [])
+        self.mailing_list.add_member(self.member)
+        self.assertTrue(self.member.address in \
+                        self.mailing_list.members_addresses())
+
+    def test_add_member(self):
+        self.assertTrue(self.mailing_list.add_member(self.member))
+        self.assertTrue(self.member.address in \
+                        self.mailing_list.members_addresses())
+        # check what happens if the member is already there:
+        self.assertFalse(self.mailing_list.add_member(self.member))
+        # check what happens if we try to add something that is not
+        # a valid Member instance
+        with self.assertRaises(TypeError):
+            self.mailing_list.add_member(None)
+            self.mailing_list.add_member('Not a member object')
+            self.mailing_list.add_member(self.mailing_list)
+
+    def test_add_member_by_address(self):
+        self.assertTrue(self.mailing_list.add_member_by_address(self.member.address))
+        self.assertTrue(self.member.address in \
+                        self.mailing_list.members_addresses())
+        # check what happens if the member is already there:
+        self.assertFalse(self.mailing_list.add_member_by_address(self.member.address))
+        # check what happens if we try to add something that is not
+        # a valid Member instance
+        with self.assertRaises(ValueError):
+            self.mailing_list.add_member_by_address(self.member)
+            self.mailing_list.add_member_by_address(None)            
+            self.mailing_list.add_member_by_address('Not a member object')
+            self.mailing_list.add_member_by_address(self.mailing_list)
+
+    def test_delete_member(self):
+        self.assertFalse(self.mailing_list.delete_member(self.member))
+        self.mailing_list.add_member(self.member)
+        self.assertTrue(self.member.address in \
+                        self.mailing_list.members_addresses())
+        self.assertTrue(self.mailing_list.delete_member(self.member))
+        self.assertFalse(self.member.address in \
+                         self.mailing_list.members_addresses())
+        with self.assertRaises(TypeError):
+            self.mailing_list.delete_member(None)
+            self.mailing_list.delete_member('Not a member object')
+            self.mailing_list.delete_member(self.mailing_list)
Index: mailjam/tests/mta.py
===================================================================
--- mailjam/tests/mta.py	(revision 16)
+++ mailjam/tests/mta.py	(revision 16)
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+
+import os, sys, multiprocessing, time
+from unittest import TestCase
+from mailjam.mta import MTAClient
+from mailjam.daemon import MailjamDaemon
+from mailjam.models import Member, MailingList
+
+
+class TestMTAClient(TestCase):
+    """
+    FIXME: These are dummy tests, they cover almost nothing from the
+    real mailjam mta client (yet)
+    """
+    def setUp(self):
+        self.mta_configfile = os.path.join(os.path.dirname(__file__),
+                                           'mailjam-mta.conf')
+        self.configfile = os.path.join(os.path.dirname(__file__),
+                                       'mailjam.conf')
+        self.mailing_list = MailingList('test_list', 'test_list@example.com',
+                                        members={}, configfile=self.configfile)
+        self.member =  Member('test@example.com')
+        self.raw_email_file = os.path.join(os.path.dirname(__file__),
+                                           'sample_raw_email.txt')
+        tmp_to_read = open(self.raw_email_file, 'r')
+        self.raw_email = tmp_to_read.read()
+        tmp_to_read.close()
+
+    def test___init__(self):
+        # in order to start mta client instances, we need to have a mailjam
+        # daemon running on the background
+        # This should be added to the setUp() method, but then it would be
+        # more difficult to terminate the process after all the methods
+        # were called
+        daemon = MailjamDaemon(self.configfile)
+        daemon.port = 9100
+        p = multiprocessing.Process(target=daemon.run)
+        p.start()
+        # Add a delay here to allow the server to be fully started before
+        # starting to send requests from the client
+        time.sleep(1)
+
+        with self.assertRaises(ValueError):
+            mta = MTAClient(self.mailing_list, self.mta_configfile)
+            mta = MTAClient(self.member, self.mta_configfile)
+            mta = MTAClient(None, self.mta_configfile)
+        mta = MTAClient(self.mailing_list.address, self.mta_configfile)
+        self.assertTrue(isinstance(mta, MTAClient))
+        self.assertEqual(mta.address, self.mailing_list.address)
+        self.assertEqual(mta.suscriptors, self.mailing_list.members_addresses)
+        self.assertEqual(mta.reply_to, self.mailing_list.address)
+
+        p.terminate()
+
+    def test_get_raw_email(self):
+        # in order to start mta client instances, we need to have a mailjam
+        # daemon running on the background
+        # This should be added to the setUp() method, but then it would be
+        # more difficult to terminate the process after all the methods
+        # were called
+        daemon = MailjamDaemon(self.configfile)
+        daemon.port = 9100
+        p = multiprocessing.Process(target=daemon.run)
+        p.start()
+        # Add a delay here to allow the server to be fully started before
+        # starting to send requests from the client
+        time.sleep(1)
+
+        mta = MTAClient(self.mailing_list.address, self.mta_configfile)
+
+        sys_stdin = sys.stdin
+        sys.stdin = open(self.raw_email_file, 'r')
+        self.assertEqual(mta.get_raw_email(),
+                         self.raw_email)
+        sys.stdin.close()
+        with self.assertRaises(IOError):
+            mta.get_raw_email()
+
+        tmp_file= open(self.raw_email_file('r'))
+        raw_data = tmp_file.read()
+        tmp_file.close()
+        self.assertEqual(mta.get_raw_email(raw_data),
+                         self.raw_email)
+
+        p.terminate()
+
+    #def save_raw_email(self):
+    #    sys_stdin = sys.stdin
+    #    sys.stdin = open(self.raw_email_file, 'r')
+    #    self.mta.save_raw_email.filename = '/tmp/mailjam-test-mta-save-raw-email'
+    
+        
+        
+        
+            
+            
+        
Index: mailjam/tests/sample_raw_email.txt
===================================================================
--- mailjam/tests/sample_raw_email.txt	(revision 16)
+++ mailjam/tests/sample_raw_email.txt	(revision 16)
@@ -0,0 +1,179 @@
+From root@fenrir.codigo23.lab Mon May 14 03:22:20 2012
+Return-Path: <root@fenrir.codigo23.lab>
+Received: from fenrir.codigo23.lab (localhost [127.0.0.1])
+	by fenrir.codigo23.lab (8.14.5/8.14.5) with ESMTP id q4D1MNxD038292
+	for <root@fenrir.codigo23.lab>; Sun, 13 May 2012 03:22:23 +0200 (CEST)
+	(envelope-from root@fenrir.codigo23.lab)
+Received: (from root@localhost)
+	by fenrir.codigo23.lab (8.14.5/8.14.5/Submit) id q4D1MNLp038270
+	for root; Sun, 13 May 2012 03:22:23 +0200 (CEST)
+	(envelope-from root)
+Date: Sun, 13 May 2012 03:22:23 +0200 (CEST)
+From: Charlie Root <root@fenrir.codigo23.lab>
+Message-Id: <201205130122.q4D1MNLp038270@fenrir.codigo23.lab>
+To: root@fenrir.codigo23.lab
+Subject: fenrir.codigo23.lab security run output
+
+
+Checking setuid files and devices:
+
+Checking for uids of 0:
+root 0
+toor 0
+
+Checking for passwordless accounts:
+
+Checking login.conf permissions:
+
+Checking for ports with mismatched checksums:
+
+fenrir.codigo23.lab kernel log messages:
++++ /tmp/security.94lpgJ1k	2012-05-13 03:22:14.000000000 +0200
++Accounting disabled
++Accounting enabled
++Accounting disabled
++Accounting enabled
+
+fenrir.codigo23.lab login failures:
+
+fenrir.codigo23.lab refused connections:
+
+Checking for a current audit database:
+
+Database created: Sat May 12 03:20:04 CEST 2012
+
+Checking for packages with security vulnerabilities:
+
+Affected package: nvidia-driver-285.05.09
+Type of problem: NVIDIA UNIX driver -- access to arbitrary system memory.
+Reference: http://portaudit.FreeBSD.org/b91234e7-9a8b-11e1-b666-001636d274f3.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/94c0ac4f-9388-11e1-b242-00262d5ed8ee.html
+
+Affected package: firefox-8.0,1
+Type of problem: mozilla -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/380e8c56-8e32-11e1-9580-4061862b8c22.html
+
+Affected package: png-1.4.8
+Type of problem: png -- memory corruption/possible remote code execution.
+Reference: http://portaudit.FreeBSD.org/262b92fe-81c8-11e1-8899-001ec9578670.html
+
+Affected package: freetype2-2.4.7
+Type of problem: freetype -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/462e2d6c-8017-11e1-a571-bcaec565249c.html
+
+Affected package: mutt-devel-1.5.21_3
+Type of problem: mutt-devel -- failure to check SMTP TLS server certificate.
+Reference: http://portaudit.FreeBSD.org/49314321-7fd4-11e1-9582-001b2134ef46.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/057130e6-7f61-11e1-8a43-00262d5ed8ee.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/b8f0a391-7910-11e1-8a43-00262d5ed8ee.html
+
+Affected package: raptor2-2.0.4_1
+Type of problem: raptor/raptor2 -- XXE in RDF/XML File Interpretation.
+Reference: http://portaudit.FreeBSD.org/60f81af3-7690-11e1-9423-00235a5f2c9a.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/330106da-7406-11e1-a1d7-00262d5ed8ee.html
+
+Affected package: libtasn1-2.11
+Type of problem: libtasn1 -- ASN.1 length decoding vulnerability.
+Reference: http://portaudit.FreeBSD.org/2e7e9072-73a0-11e1-a883-001cc0a36e12.html
+
+Affected package: gnutls-2.12.14
+Type of problem: libtasn1 -- ASN.1 length decoding vulnerability.
+Reference: http://portaudit.FreeBSD.org/2e7e9072-73a0-11e1-a883-001cc0a36e12.html
+
+Affected package: gnutls-2.12.14
+Type of problem: gnutls -- possible overflow/Denial of service vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/aecee357-739e-11e1-a883-001cc0a36e12.html
+
+Affected package: firefox-8.0,1
+Type of problem: mozilla -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/a1050b8b-6db3-11e1-8b37-0011856a6e37.html
+
+Affected package: portaudit-0.5.17
+Type of problem: portaudit -- auditfile remote code execution.
+Reference: http://portaudit.FreeBSD.org/6d329b64-6bbb-11e1-9166-001e4f0fb9b1.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- Errant plug-in load and GPU process memory corruption.
+Reference: http://portaudit.FreeBSD.org/ab1f515d-6b69-11e1-8288-00262d5ed8ee.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- cross-site scripting vulnerability.
+Reference: http://portaudit.FreeBSD.org/1015e1fe-69ce-11e1-8288-00262d5ed8ee.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/99aef698-66ed-11e1-8288-00262d5ed8ee.html
+
+Affected package: postgresql-client-8.4.10
+Type of problem: databases/postgresql*-client -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/174b8864-6237-11e1-be18-14dae938ec40.html
+
+Affected package: libxml2-2.7.8_1
+Type of problem: libxml2 -- heap buffer overflow.
+Reference: http://portaudit.FreeBSD.org/57f1a624-6197-11e1-b98c-bcaec565249c.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/2f5ff968-5829-11e1-8288-00262d5ed8ee.html
+
+Affected package: python24-2.4.5_8
+Type of problem: Python -- DoS via malformed XML-RPC / HTTP POST request.
+Reference: http://portaudit.FreeBSD.org/b4f8be9e-56b2-11e1-9fb7-003067b2972c.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/fe1976c2-5317-11e1-9e99-00262d5ed8ee.html
+
+Affected package: firefox-8.0,1
+Type of problem: mozilla -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/0a9e2b72-4cb7-11e1-9146-14dae9ebcf89.html
+
+Affected package: sudo-1.8.3_1
+Type of problem: sudo -- format string vulnerability.
+Reference: http://portaudit.FreeBSD.org/7c920bb7-4b5f-11e1-9f47-00e0815b8da8.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/33d73d59-4677-11e1-88cd-00262d5ed8ee.html
+
+Affected package: wireshark-1.6.2
+Type of problem: Wireshark -- Multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/3ebb2dc8-4609-11e1-9f47-00e0815b8da8.html
+
+Affected package: ffmpeg-0.7.8,1
+Type of problem: ffmpeg -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/ea2ddc49-3e8e-11e1-8095-5404a67eef98.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/1a1aef8e-3894-11e1-8b5c-00262d5ed8ee.html
+
+Affected package: firefox-8.0,1
+Type of problem: mozilla -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/e3ff776b-2ba6-11e1-93c6-0011856a6e37.html
+
+Affected package: chromium-15.0.874.121
+Type of problem: chromium -- multiple vulnerabilities.
+Reference: http://portaudit.FreeBSD.org/68ac6266-25c3-11e1-b63a-00262d5ed8ee.html
+
+Affected package: libXfont-1.4.4,1
+Type of problem: libXfont -- possible local privilege escalation.
+Reference: http://portaudit.FreeBSD.org/304409c3-c3ef-11e0-8aa5-485d60cb5385.html
+
+32 problem(s) in your installed packages found.
+
+You are advised to update or deinstall the affected package(s) immediately.
+
+-- End of security output --
Index: mailjam/tools.py
===================================================================
--- mailjam/tools.py	(revision 16)
+++ mailjam/tools.py	(revision 16)
@@ -0,0 +1,34 @@
+# -*- coding: utf-8 -*-
+
+"""
+The mailjam project - tools.py
+
+This file is released under the BSD license, see LICENSE for
+more information.
+
+Francisco de Borja Lopez Rio - <borja@codigo23.net>
+Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
+"""
+
+import re
+
+def validate_email_address(address):
+
+    """
+    This function validates a given address, returning True
+    if it is a valid address, False otherwise.
+
+    The function uses a regexp from the django project, and
+    it is inspired in this snippet:
+
+    http://djangosnippets.org/snippets/1093/
+    """
+
+    if not isinstance(address, str):
+        return False
+
+    email_re = re.compile(
+    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
+    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
+    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
+    return True if email_re.match(address) else False
Index: stman/__init__.py
===================================================================
--- postman/__init__.py	(revision 4)
+++ 	(revision )
@@ -1,4 +1,0 @@
-# -*- coding: utf-8 -*-
-
-from models import Member, MailingList
-from storage import JsonStorage
Index: stman/archives/README
===================================================================
--- postman/archives/README	(revision 2)
+++ 	(revision )
@@ -1,1 +1,0 @@
-Default archives location
Index: stman/config.py
===================================================================
--- postman/config.py	(revision 15)
+++ 	(revision )
@@ -1,105 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - config.py
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-import os
-from ConfigParser import SafeConfigParser
-
-class DaemonConfig():
-    def __init__(self, configfile=None):
-        self.configfile = configfile
-        self.default_paths = ['/usr/local/etc/postman', '/usr/local/etc',
-                              '/etc/postman', '/etc',
-                              os.path.join(os.path.dirname(__file__),'../conf')]
-        self.config = {}
-
-    @property
-    def default_filename(self):
-        """
-        Method to get the default configuration filename. It is a method instead
-        of an attribute for easier subclassing
-        """
-        return 'postman.conf'
-
-    @property
-    def sections(self):
-        """
-        Method to get the list of available sections in the configuration file.
-        It is a method instead of an attribute for easier subclassing.
-
-        FIXME: Perhaps it would be better to dinamically get the list of
-        sections from the configuration file itself.
-        """
-        return ['xmlrpc_server', 'storage', 'archive',
-                'mailing_lists', 'members']
-    
-    def validate_configfile(self):        
-        if self.configfile:
-            if not os.path.exists(self.configfile):
-                # the file does not exist, so we override it with None,
-                # allowing the next few lines to search for a valid
-                # config file on the usual places
-                self.configfile = None
-            
-        if not self.configfile:
-            for path in self.default_paths:
-                full_path = os.path.join(path, self.default_filename)
-                if os.path.exists(full_path):
-                    self.configfile = full_path
-                    return full_path
-                
-        # if we reach here, self.configfile will be still None, no valid
-        # config files were found, and so we raise an exception
-        raise IOError('ERROR - Can not find ' + self.default_filename + \
-                      ' in your environment')
-
-    def load(self):
-        if not self.configfile:
-            self.validate_configfile()
-        parser = SafeConfigParser()
-        parser.read(self.configfile)
-        for section in self.sections:
-            self.config[section] = {}
-            for name, value in parser.items(section):
-                self.config[section][name] = value
-        return self.config        
-
-    def get_section_parameters(self, section):
-        if section not in self.sections:
-            raise IndexError('ERROR - ' + section + \
-                             ' is not one of the available sections: ' + \
-                             ', '.join(self.sections))
-        if section not in self.config.keys():
-            # perhaps the config hasn't been loaded yet
-            self.load()
-
-        return self.config[section]
-
-class MTAClientConfig(DaemonConfig):
-    @property
-    def default_filename(self):
-        return 'postman-mta.conf'
-
-    @property
-    def sections(self):
-        return ['server', 'archive']
-
-
-def get_config_parameters(section=None, configfile=None):
-    """
-    This function is kept here for backwards compatibility.
-    By default all the daemon code will use this function to get
-    configuration parameters from the default configuration file.
-    """
-    config = DaemonConfig(configfile)
-    return config.get_section_parameters(section)
-
-    
Index: stman/daemon.py
===================================================================
--- postman/daemon.py	(revision 15)
+++ 	(revision )
@@ -1,245 +1,0 @@
-# -*- coding: utf-8 -*-
-
-import os, inspect, logging
-from SimpleXMLRPCServer import SimpleXMLRPCServer, list_public_methods
-
-from postman import config
-from postman.models import Member, MailingList
-from postman.storage import JsonStorage as Storage
-
-
-class Postman():
-
-    def __init__(self, configfile=None):
-        self.storage_config = config.get_config_parameters('storage',
-                                                           configfile)
-        self.archive_config = config.get_config_parameters('archive',
-                                                           configfile)
-
-        # lists were the currently managed mailing lists information is going
-        # to be saved
-        self.mailings = {}
-        self.mailings_addresses = []
-        
-        # the files were internal information (like active mailing lists,
-        # members, etc) is saved
-        self.dbs = {'mailings': Storage(self.storage_config['lists_db']),
-                    'members': Storage(self.storage_config['members_db'])}
-
-    def save(self):
-        """
-        Save all the current managed data to disk
-        """
-        if self.mailings:
-            # Save the config file from where we can reload information about
-            # the mailing lists managed by this postman instance
-            self.dbs['mailings'].write(self.mailings_addresses)
-            # Save each mailing list data into its separated persistence file
-            for m in self.mailings.keys():            
-                self.mailings[m].save()
-            return True
-        return False
-
-    def load(self):
-        """
-        Load all data from the storage files
-        """
-        if self.dbs['mailings'].exists():
-            # load the list of managed mailing lists
-            # FIXME: This is quite naive, we do not perform any check here after
-            # loading the data from the json file, which can be modified by
-            # untrustred users.
-            self.mailings_addresses = self.dbs['mailings'].read()
-
-            # now load all the mailing objects:
-            for address in self.mailings_addresses:
-                mailing = MailingList(address, address)
-                mailing.load()
-                self.mailings[address] = mailing                
-            return True
-        return False
-
-    def clear(self):
-        """
-        Delete all stored data from disk (useful for testing).
-        DANGER: Calling this method will remove all data from disk, leaving the
-        postman instance with no persistence data, if the postman process die,
-        before another .save() call is made, all data will be lost.
-        """
-        if self.dbs['mailings'].exists():
-            # We do not delete each mailing list file, but only the file
-            # containing the list of existing mailing lists
-            self.dbs['mailings'].delete()
-            return True
-        return False
-
-    def add_mailing_list(self, info={}):
-        """
-        Add a new mailing list to this postman instance. expects one parameter,
-        info, which is a dictionary that should contain, at least, the
-        following keys:
-
-         - name: (string) the name we will give to the list
-         - address: (string) the email address of the list
-         - members: (list) a list of email adddress of the list members
-         
-        """
-        if not isinstance(info, dict):
-            raise TypeError(info, ' is not a valid dictionary')
-
-        if 'name' not in info.keys() or \
-           'address' not in info.keys() or \
-           'members' not in info.keys() or \
-           'configfile' not in info.keys():
-            raise ValueError(info, ' does not seem to be a valid configuration')
-        
-        if info['address'] in self.mailings_addresses:
-            raise IndexError(info['address'],
-                             ' has been already added to postman')
-
-        mailing = MailingList(info['name'], info['address'],
-                              info['members'], info['configfile'])
-        self.mailings[mailing.address] = mailing
-        self.mailings_addresses.append(mailing.address)
-        # After adding new mailings, save them to disk
-        self.save()
-        return True
-        
-    def add_mailing_member(self, member_addr=None, list_addr=None):
-        """
-        Add a new member for the mailing list represented by list_addr (a string
-        containing the email address of any mailing list managed by this postman
-        instance). member_addr is a string representing the email address of the
-        new member
-        """
-
-        if not member_addr:
-            raise ValueError(member_addr, 'missing member address')
-
-        if not list_addr:
-            raise ValueError(list_addr, 'missing list address')
-
-        if list_addr not in self.mailings_addresses:
-            # FIXME: Perhaps we should add it, perhaps not (mispelled address?)
-            raise IndexError(list_addr, ' is not a valid mailing list')
-
-        added = self.mailings[list_addr].add_member_by_address(member_addr)
-        if added:
-            self.save()
-        return added
-
-
-class PostmanXMLRPC():
-    """
-    This class is a wrapper we will use to limit the methods that will be
-    published through the XMLRPC link. Only the methods from this class
-    will be available through that link.
-
-    As we use dotted names to separate xmlrpc-exported methods into different
-    namespaces, this class contains nothing, it will be used only for
-    method-registering purposes. The MailingListXMLRPC and MemberXMLRPC classes
-    contain the actual methods that are published.
-
-    More information on this approach here:
-
-    http://www.doughellmann.com/PyMOTW/SimpleXMLRPCServer/#exposing-methods-of-objects
-    """
-
-    def _listMethods(self):
-        public_methods = []
-        public_methods += ['lists.'+i for i in dir(MailingListXMLRPC) if '_' not in i]
-        public_methods += ['members.'+i for i in dir(MemberXMLRPC) if '_' not in i]
-        return public_methods
-
-    def _methodHelp(self, method):
-        f = getattr(self, method)
-        return inspect.getdoc(f)
-
-
-class MailingListXMLRPC():
-    def __init__(self):
-        self.postman = Postman()
-        self.postman.load()
-    def add(self, info={}):
-        self.postman.add_mailing_list(info)
-    def addresses(self):
-        return self.postman.mailings_addresses    
-
-
-class MemberXMLRPC():
-    def __init__(self):
-        self.postman = Postman()
-        self.postman.load()
-    def add(self, member_addr=None, list_addr=None):
-        self.postman.add_mailing_member(member_addr, list_addr)
-    def list(self, mailing):
-        if mailing in self.postman.mailings_addresses:
-            return self.postman.mailings[mailing].members_addresses()
-
-
-class PostmanDaemon():
-    def __init__(self, configfile=None):
-        self.config = config.get_config_parameters('xmlrpc_server', configfile)
-
-        # FIXME: These should be loaded from a config file
-        self.address = self.config.get('address', 'localhost')
-        self.port = int(self.config.get('port', 9876))
-        self.logfile = self.config.get('logfile',
-                                       os.path.join(os.path.dirname(__file__),
-                                                    'server.log'))
-        logging.basicConfig(filename=self.logfile, level=logging.DEBUG)
-        self.server = None
-        self.ready_to_serve = False
-        
-    def create_server(self):
-        """
-        If there is no server initialized in self.server, create an instance
-        of SimpleXMLRPCServer in that attribute. If there is already a server
-        initialized there, simply return True
-        """           
-        if not self.server:
-            msg = 'Creating XMLRPC server object on {}:{}'.format(self.address,
-                                                                  self.port)
-            logging.info(msg)
-            self.server = SimpleXMLRPCServer((self.address, self.port),
-                                             allow_none=True,
-                                             logRequests=False)
-            self.server.register_introspection_functions()
-        return True
-
-    def add_methods(self):
-        """
-        Check if there is an initialized server (initialize it if there is none)
-        and then register all the Postman public methods to be served through
-        the xml-rpc link
-
-        Once the methods are registered set self.ready_to_serve to True        
-        """
-        if not self.server:
-            # ensure there is an XMLRPC server initialized
-            self.create_server()
-        msg = 'Registering public methods'
-        logging.info(msg)
-        root = PostmanXMLRPC()
-        root.lists = MailingListXMLRPC()
-        root.members = MemberXMLRPC()
-        self.server.register_instance(root, allow_dotted_names=True)
-        self.ready_to_serve = True
-        return self.ready_to_serve
-            
-    def run(self):
-        """
-        Run the xmlrpc daemon. If self.ready_to_serve is False, call
-        self.add_methods, which will initialize the server and will register all
-        the public methods into that server
-        """
-        if not self.ready_to_serve:
-            self.add_methods()
-        msg = 'Starting XMLRPC server on {}:{}'.format(self.address,
-                                                       self.port)
-        logging.info(msg)
-        try:
-            self.server.serve_forever()
-        except KeyboardInterrupt:
-            msg = 'Stopping server'
-            logging.info(msg)
Index: stman/models.py
===================================================================
--- postman/models.py	(revision 11)
+++ 	(revision )
@@ -1,129 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - models.py
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-import os
-from tools import validate_email_address
-from storage import JsonStorage as Storage
-import config
-
-class Member():
-
-    """
-    Class that defines a mailing list member
-    """
-
-    def __init__(self, address):
-        self.address = self._validate_address(address)
-        
-    def __repr__(self):
-        return "<Member '%s'>" % self.address
-
-    def __str__(self):
-        return self.address
-
-    def _validate_address(self, address):
-        if not validate_email_address(address):
-            raise ValueError(address, ' is not a valid email address')
-        return address
-
-
-class MailingList():
-
-    """
-    Class that defines a mailing list
-    """
-
-    def __init__(self, name, address, members={}, configfile=None):
-        self.configfile = configfile
-        self.storage_config = config.get_config_parameters('storage',
-                                                           configfile)
-        self.archive_config = config.get_config_parameters('archive',
-                                                           configfile)
-        self.mailing_config = config.get_config_parameters('mailing_lists',
-                                                           configfile)
-        self.name = name
-        self.address = address
-        self.members = members
-        
-    def __repr__(self):
-        return "<MailingList '%s'>" % self.address
-
-    def __str__(self):
-        return self.address
-        
-    def _validate_member_object(self, member=None):
-        if not isinstance(member, Member):
-            raise TypeError(member, ' is not a valid Member instance')
-        return member
-
-    def _validate_member(self, member=None):
-        member = self._validate_member_object(member)
-        return member.address in self.members_addresses()
-
-    def _validate_member_by_address(self, address=None):
-        if not validate_email_address(address):
-            raise ValueError(address, ' is not a valid email address')
-        return address in self.members_addresses()
-
-    @property
-    def storage(self):
-        return Storage(os.path.join(self.storage_config['path'], self.address))
-
-    @property
-    def archive(self):
-        return Storage(os.path.join(self.archive_config['path'], self.address))
-    
-    def members_addresses(self):
-        return self.members.keys()
-
-    def add_member(self, member):
-        member = self._validate_member_object(member)
-        if self._validate_member(member):
-            return False
-        self.members[member.address] = member
-        return True
-
-    def add_member_by_address(self, address=None):
-        if self._validate_member_by_address(address):
-            return False
-        member = Member(address)
-        self.members[address] = member
-        return True
-                
-    def delete_member(self, member=None):
-        member = self._validate_member_object(member)
-        if not self._validate_member(member):
-            return False
-        del self.members[member.address]
-        return True
-
-    def info(self):
-        """
-        Returns a dict we can use to add this mailing list to a postman
-        instance
-        """
-        # FIXME: This code could be replaced with something that
-        # automagically generates the dict from the instance attributes
-        return {'name': self.name, 'address': self.address,
-                'members': self.members, 'configfile': self.configfile}
-
-    def load(self):
-        if self.storage.exists():
-            data = self.storage.read()
-            self.name = data.name
-            self.address = data.address
-            self.members = data.members
-            return True
-        return False
-    
-    def save(self):
-        self.storage.write(self)
Index: stman/mta.py
===================================================================
--- postman/mta.py	(revision 15)
+++ 	(revision )
@@ -1,113 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - mta.py
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-import os, sys, email, smtplib, xmlrpclib
-from datetime import datetime
-from postman.models import MailingList
-from postman.config import MTAClientConfig
-from postman.tools import validate_email_address
-
-class MTAClient():
-    
-    def __init__(self, address=None, configfile=None):
-        if not validate_email_address(address):
-            raise ValueError(address, ' is not a valid email address')
-
-        mta_config = MTAClientConfig()
-        mta_config.load()
-        self.config = mta_config.config
-        self.rpc = xmlrpclib.ServerProxy(self.config['server']['uri'])
-        self.address = self._validate_address(address)
-        self.suscriptors = self.rpc.members.list(address)
-        self.reply_to = self.address
-        self.raw_email = None
-        self.queue = []
-
-    def _validate_archive_path(self):
-        """
-        Validate that the archive path exists. If not, try to create it
-        """
-        if not os.path.exists(self.config['archive']['path']):
-            # FIXME: This will raise an IOError if the user has no
-            # privileges to create the directory, perhaps we should catch
-            # that and show an error instead
-            os.makedirs(self.config['archive']['path'])
-        return True        
-        
-    def _validate_address(self, address=None):
-        """
-        The address provided by the user will be valid only if it is a
-        valid email address and if it is the email address of an already
-        existing mailing list
-        """
-        if not validate_email_address(address):
-            raise ValueError(address, ' is not a valid email address')
-        if not address in self.rpc.lists.addresses():
-            raise ValueError(address,
-                             ' is not the address of any existing mailing list')
-        # If it is valid, return it
-        return address
-    
-    def get_raw_email(self, raw_email=None):
-        """
-        get the raw data containing email information. If raw_email is None,
-        try to get the data from stdin
-        """
-        if not raw_email:
-            try:
-                self.raw_email = sys.stdin.read()
-            except:
-                raise IOError('Can not get a valid email from stdin')
-        else:
-            self.raw_email = raw_email
-        # FIXME: We should perform some checks on the raw data, ensuring
-        # it is a valid email text
-        return self.raw_email
-
-    def save_raw_email(self):
-        if not self.raw_email:
-            # FIXME: perhaps a while loop here, with some maximum recursion
-            # check, would be nice here
-            self.get_raw_email()
-        # Check the path to the archive exists
-        self._validate_archive_path()
-        filename = os.path.join(self.config['archive']['path'],
-                                datetime.today().strftime('%Y%d%m%H%M%S%f'))
-        tmpfile = file(filename, 'w')
-        tmpfile.write(self.raw_email)
-        tmpfile.close()
-        self.queue.append(filename)
-
-    def send_email(self):
-        """
-        Send emails from the queue, if there is any
-        """
-        if self.queue:
-            next_email = self.queue.pop()
-            email_file = file(next_email, 'r')
-            email_data = email.message_from_file(email_file)
-            email_file.close()
-            email_data['Reply-to'] = self.reply_to
-            print 'SENDING EMAIL:'
-            print email_data
-            #smtp_conn = smtplib.SMTP()
-            #smtp_conn.connect()
-            #smtp_conn.sendmail(email_data['From'], self.suscriptors,
-            #                   email_data.as_string())
-            #smtp_conn.close()
-            # FIXME: enable tmp data removal here:
-            # if not self.config['archive']['persistent']:
-            #     REMOVE THE FILE FROM DISK
-
-    def run(self):
-        self.save_raw_email()
-        self.send_email()
Index: stman/storage.py
===================================================================
--- postman/storage.py	(revision 11)
+++ 	(revision )
@@ -1,100 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - storage.py
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-import os, errno, json
-
-
-class JsonStorage():
-
-    """
-    Json-based storage. 
-    """
-
-    def __init__(self, path='storage.json'):
-        if os.path.isdir(path):
-            raise IOError(path, ' is a directory, exiting')
-        self.path = path
-
-    def exists(self):
-        return os.path.exists(self.path)    
-
-    def create(self):
-        """
-        Ensure all the subdirectories in the path to the storage file
-        exist
-        """
-        try:
-            os.makedirs(os.path.dirname(self.path))
-        except OSError, e:
-            # If the dir already exists do not complain, if it is
-            # any other error, raise the exception
-            if e.errno != errno.EEXIST:
-                raise
-    
-    def jsonize(self, obj):
-        """
-        Convert objects to a dictionary of their representation
-        Based on the exmplaes from Doyg Hellmann:
-        http://www.doughellmann.com/PyMOTW/json/#working-with-your-own-types
-        """
-        jobj = { '__class__':obj.__class__.__name__, 
-                 '__module__':obj.__module__,
-                 }
-        jobj.update(obj.__dict__)
-        return jobj
-
-    def dejsonize(self, jobj):
-        """
-        Convert some data that has been "jsonized" to the original
-        python object. Again, based on the examples from Doug Hellmann
-        """
-        if '__class__' in jobj:
-            class_name = jobj.pop('__class__')
-            module_name = jobj.pop('__module__')
-            module = __import__(module_name)
-            class_ = getattr(module, class_name)
-            args = dict((key.encode('ascii'), value) \
-                        for key, value in jobj.items())
-            return class_(**args)
-        return jobj
-        
-    def write(self, data):
-        if not self.exists():
-            # ensure the path to the storage file exists
-            self.create()
-        with open(self.path, 'w') as storage:
-            json.dump(data, storage, sort_keys=True, indent=4,
-                      default=self.jsonize)
-            return True 
-        return False 
-
-    def read(self):        
-        with open(self.path, 'r') as storage:
-            try:
-                data = json.load(storage,object_hook=self.dejsonize)
-            except ValueError:
-                # if no json data could be imported, the file could be
-                # damaged or perhaps it does not containg json-encoded
-                # data, simply return an empty string
-                #
-                # FIXME: we should notify the user about the problem
-                return ''
-        return data
-
-    def delete(self):
-        """
-        Remove the storage file
-        """
-        if self.exists():
-            os.remove(self.path)
-            return True
-        return False
Index: stman/storage/README
===================================================================
--- postman/storage/README	(revision 2)
+++ 	(revision )
@@ -1,1 +1,0 @@
-Default storage location
Index: stman/storage/mailings/README
===================================================================
--- postman/storage/mailings/README	(revision 2)
+++ 	(revision )
@@ -1,1 +1,0 @@
-Default mailing list storage location
Index: stman/tests/__init__.py
===================================================================
--- postman/tests/__init__.py	(revision 15)
+++ 	(revision )
@@ -1,15 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - tests module
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-from models import *
-# from mta import *
-from daemon import *
Index: stman/tests/daemon.py
===================================================================
--- postman/tests/daemon.py	(revision 11)
+++ 	(revision )
@@ -1,202 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - daemon.py
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-import os, multiprocessing, xmlrpclib, time
-from SimpleXMLRPCServer import SimpleXMLRPCServer
-from unittest import TestCase
-
-from postman.daemon import Postman, PostmanXMLRPC, PostmanDaemon
-from postman.models import Member, MailingList
-from postman.storage import JsonStorage as Storage
-
-
-class TestPostman(TestCase):
-    """
-    postman.daemon.Postman tests.
-
-    Remember to call the .clear() method of postman after each test, so
-    the temp storage files are deleted
-    """
-    def setUp(self):
-        self.configfile = os.path.join(os.path.dirname(__file__), 'postman.conf')
-        self.mailing_list = MailingList('test_list', 'test_list@example.com',
-                                        members={}, configfile=self.configfile)
-        self.member =  Member('test@example.com')
-
-    def test___init__(self):
-        postman = Postman(configfile=self.configfile)
-        self.assertIsInstance(postman, Postman)
-        self.assertEqual(postman.mailings, {})
-        self.assertEqual(postman.mailings_addresses, [])
-        self.assertIsInstance(postman.dbs, dict)
-        self.assertTrue('mailings' in postman.dbs.keys())
-        self.assertTrue('members' in postman.dbs.keys())
-        self.assertIsInstance(postman.dbs['mailings'], Storage)
-        self.assertIsInstance(postman.dbs['members'], Storage)
-
-    def test_save(self):
-        postman = Postman(configfile=self.configfile)
-        self.assertFalse(postman.save())
-        postman.add_mailing_list(self.mailing_list.info())
-        self.assertTrue(postman.save())
-        # FIXME: We have to test here that the generated json file
-        # contains the data it should contain
-
-        # Clear the files created by the tests
-        postman.clear()
-
-    def test_load(self):
-        postman = Postman(configfile=self.configfile)
-        self.assertFalse(postman.mailings)
-        self.assertFalse(postman.mailings_addresses)
-        self.assertFalse(postman.load())
-        postman.add_mailing_list(self.mailing_list.info())
-        self.assertTrue(postman.load())
-
-        # Check that another postman instance is able to load the saved data
-        postman_load = Postman(configfile=self.configfile)
-        self.assertFalse(postman_load.mailings)
-        self.assertFalse(postman_load.mailings_addresses)
-        postman_load.load()
-        self.assertTrue(postman_load.mailings)
-        self.assertIsInstance(postman_load.mailings, dict)
-        self.assertTrue(postman_load.mailings_addresses)
-        self.assertIsInstance(postman_load.mailings_addresses, list)        
-
-        # Clear the files created by the tests
-        postman.clear()
-
-    def test_clear(self):
-        postman = Postman(configfile=self.configfile)
-        self.assertFalse(postman.clear())
-        postman.add_mailing_list(self.mailing_list.info())
-        self.assertTrue(postman.clear())
-
-    def test_add_mailing_list(self):
-        postman = Postman(configfile=self.configfile)
-        with self.assertRaises(TypeError):
-            # test improper info values
-            postman.add_mailing_list(['a list', 'is an', 'invalid parameter'])
-            postman.add_mailing_list(self.mailing_list)
-        with self.assertRaises(ValueError):
-            #test incomplete/missing info values
-            postman.add_mailing_list()
-            postman.add_mailing_list({'name': 'missing info'})
-            postman.add_mailing_list({'address': 'missing info'})
-            postman.add_mailing_list({'name': 'missing info',
-                                      'address': 'missing info'})
-        # test mailing lists can be added
-        self.assertTrue(postman.add_mailing_list(self.mailing_list.info()))
-        self.assertTrue(postman.mailings)
-        self.assertIsInstance(postman.mailings, dict)
-        self.assertTrue(postman.mailings_addresses)
-        self.assertIsInstance(postman.mailings_addresses, list)
-        with self.assertRaises(IndexError):
-            # test what happens when the mailing has been already added
-            postman.add_mailing_list(self.mailing_list.info())
-
-        # Clear the files created by the tests
-        postman.clear()
-
-    def test_add_mailing_member(self):
-        postman = Postman(configfile=self.configfile)
-        postman.add_mailing_list(self.mailing_list.info())
-        with self.assertRaises(ValueError):
-            # test what happens if we call the method without proper
-            # parameters
-            postman.add_mailing_member()
-            postman.add_mailing_member(None, None)
-            postman.add_mailing_member(None, 'test_list@example.net')
-            postman.add_mailing_member('test@example.net', None)
-            postman.add_mailing_member('test@example', 'test_list@example.net')
-        with self.assertRaises(IndexError):
-            # test if we try to add a member to a non-existing mailing list
-            postman.add_mailing_member('test@example.net',
-                                       'test_list_b@example.net')
-        # Test adding a member
-        self.assertTrue(postman.add_mailing_member('test@example.net',
-                                                   self.mailing_list.address))
-        # Test trying to re-add that user
-        self.assertFalse(postman.add_mailing_member('test@example.net',
-                                                    self.mailing_list.address))
-
-        # Clear the files created by the tests
-        postman.clear()
-
-
-class TestPostmanDaemon(TestCase):
-    """
-    postman.daemon.PostmanDaemon tests.
-
-    Remember to call the .clear() method of postman after each test, so
-    the temp storage files are deleted
-    """
-    def setUp(self):
-        self.configfile = os.path.join(os.path.dirname(__file__),
-                                       'postman.conf')
-        self.mailing_list = MailingList('test_xmlrpc',
-                                        'test_xmlrpc@example.com', members={},
-                                        configfile=self.configfile)
-        self.member =  Member('test@example.com')
-
-    def test___init__(self):
-        daemon = PostmanDaemon(self.configfile)
-        self.assertIsInstance(daemon, PostmanDaemon)
-        self.assertFalse(daemon.ready_to_serve)
-        # FIXME: More tests should be added here once the configuration
-        # file feature is added        
-
-    def test_create_server(self):
-        daemon = PostmanDaemon(self.configfile)
-        daemon.port = 9001
-        self.assertTrue(daemon.create_server())
-        self.assertIsInstance(daemon.server, SimpleXMLRPCServer)
-        self.assertFalse(daemon.ready_to_serve)
-        
-    def test_add_methods(self):
-        daemon = PostmanDaemon(self.configfile)
-        daemon.port = 9002
-        self.assertTrue(daemon.add_methods())
-        self.assertTrue(daemon.ready_to_serve)
-
-        daemon = PostmanDaemon(self.configfile)
-        daemon.port = 9003        
-        daemon.create_server()
-        self.assertTrue(daemon.add_methods())
-        self.assertTrue(daemon.ready_to_serve)
-        
-    def test_run(self):
-        daemon = PostmanDaemon(self.configfile)
-        daemon.port = 9004
-        # start the daemon in another process, so we can start communicating
-        # with itjobs = []
-        p = multiprocessing.Process(target=daemon.run)
-        p.start()
-
-        # Add a delay here to allow the server to be fully started before
-        # starting to send requests from the client
-        time.sleep(2)
-        
-        # FIXME: Hardcoded url here, should be picked from a config file        
-        client = xmlrpclib.ServerProxy('http://localhost:9004')
-
-        # Check that we can perform an XMLRPC call and that the list of
-        # available public methods contains the list of methods we have
-        # defined in our base XMLRPC class
-        set_class_methods = set(PostmanXMLRPC()._listMethods())
-        set_xmlrpc_methods = set(client.system.listMethods())
-        self.assertTrue(set_class_methods.issubset(set_xmlrpc_methods))
-        
-        # Stop the server
-        p.terminate()
-        
-        
Index: stman/tests/models.py
===================================================================
--- postman/tests/models.py	(revision 10)
+++ 	(revision )
@@ -1,98 +1,0 @@
-# -*- coding: utf-8 -*-
-
-import os
-from unittest import TestCase
-from postman.models import Member, MailingList
-
-
-class TestMember(TestCase):
-    def setUp(self):
-        self.member = Member('test@example.com')
-
-    def test__validate_address(self):
-        self.assertEqual(self.member._validate_address(self.member.address),
-                         self.member.address)
-        with self.assertRaises(ValueError):
-            self.member._validate_address('notavalidemail')
-
-    
-class TestMailingList(TestCase):
-    def setUp(self):
-        configfile = os.path.join(os.path.dirname(__file__), 'postman.conf')
-        self.mailing_list = MailingList('test_list', 'test_list@example.com',
-                                        members={}, configfile=configfile)
-        self.member =  Member('test@example.com')
-
-    def test__validate_member_object(self):
-        self.assertEqual(self.mailing_list._validate_member_object(self.member),
-                         self.member)
-        with self.assertRaises(TypeError):
-            self.mailing_list._validate_member_object(None)
-            self.mailing_list._validate_member_object('Not a member object')
-            self.mailing_list._validate_member_object(self.mailing_list)
-
-    def test__validate_member(self):
-        # At first the member object is not a member of the list
-        self.assertFalse(self.mailing_list._validate_member(self.member))
-        self.mailing_list.add_member(self.member)
-        self.assertTrue(self.mailing_list._validate_member(self.member))
-        with self.assertRaises(TypeError):
-            self.mailing_list._validate_member(None)
-            self.mailing_list._validate_member('Not a member object')
-            self.mailing_list._validate_member(self.mailing_list)
-        
-    def test__validate_member_by_address(self):
-        self.assertFalse(self.mailing_list._validate_member_by_address(self.member.address))
-        self.mailing_list.add_member(self.member)
-        self.assertTrue(self.mailing_list._validate_member_by_address(self.member.address))
-        with self.assertRaises(ValueError):
-            self.mailing_list._validate_member_by_address(self.member)
-            self.mailing_list._validate_member_by_address(None)            
-            self.mailing_list._validate_member_by_address('Not a member object')
-            self.mailing_list._validate_member_by_address(self.mailing_list)
-
-    def test_members_addresses(self):
-        self.assertEqual(self.mailing_list.members_addresses(), [])
-        self.mailing_list.add_member(self.member)
-        self.assertTrue(self.member.address in \
-                        self.mailing_list.members_addresses())
-
-    def test_add_member(self):
-        self.assertTrue(self.mailing_list.add_member(self.member))
-        self.assertTrue(self.member.address in \
-                        self.mailing_list.members_addresses())
-        # check what happens if the member is already there:
-        self.assertFalse(self.mailing_list.add_member(self.member))
-        # check what happens if we try to add something that is not
-        # a valid Member instance
-        with self.assertRaises(TypeError):
-            self.mailing_list.add_member(None)
-            self.mailing_list.add_member('Not a member object')
-            self.mailing_list.add_member(self.mailing_list)
-
-    def test_add_member_by_address(self):
-        self.assertTrue(self.mailing_list.add_member_by_address(self.member.address))
-        self.assertTrue(self.member.address in \
-                        self.mailing_list.members_addresses())
-        # check what happens if the member is already there:
-        self.assertFalse(self.mailing_list.add_member_by_address(self.member.address))
-        # check what happens if we try to add something that is not
-        # a valid Member instance
-        with self.assertRaises(ValueError):
-            self.mailing_list.add_member_by_address(self.member)
-            self.mailing_list.add_member_by_address(None)            
-            self.mailing_list.add_member_by_address('Not a member object')
-            self.mailing_list.add_member_by_address(self.mailing_list)
-
-    def test_delete_member(self):
-        self.assertFalse(self.mailing_list.delete_member(self.member))
-        self.mailing_list.add_member(self.member)
-        self.assertTrue(self.member.address in \
-                        self.mailing_list.members_addresses())
-        self.assertTrue(self.mailing_list.delete_member(self.member))
-        self.assertFalse(self.member.address in \
-                         self.mailing_list.members_addresses())
-        with self.assertRaises(TypeError):
-            self.mailing_list.delete_member(None)
-            self.mailing_list.delete_member('Not a member object')
-            self.mailing_list.delete_member(self.mailing_list)
Index: stman/tests/mta.py
===================================================================
--- postman/tests/mta.py	(revision 15)
+++ 	(revision )
@@ -1,97 +1,0 @@
-# -*- coding: utf-8 -*-
-
-import os, sys, multiprocessing, time
-from unittest import TestCase
-from postman.mta import MTAClient
-from postman.daemon import PostmanDaemon
-from postman.models import Member, MailingList
-
-
-class TestMTAClient(TestCase):
-    """
-    FIXME: These are dummy tests, they cover almost nothing from the
-    real postman mta client (yet)
-    """
-    def setUp(self):
-        self.mta_configfile = os.path.join(os.path.dirname(__file__),
-                                           'postman-mta.conf')
-        self.configfile = os.path.join(os.path.dirname(__file__),
-                                       'postman.conf')
-        self.mailing_list = MailingList('test_list', 'test_list@example.com',
-                                        members={}, configfile=self.configfile)
-        self.member =  Member('test@example.com')
-        self.raw_email_file = os.path.join(os.path.dirname(__file__),
-                                           'sample_raw_email.txt')
-        tmp_to_read = open(self.raw_email_file, 'r')
-        self.raw_email = tmp_to_read.read()
-        tmp_to_read.close()
-
-    def test___init__(self):
-        # in order to start mta client instances, we need to have a postman
-        # daemon running on the background
-        # This should be added to the setUp() method, but then it would be
-        # more difficult to terminate the process after all the methods
-        # were called
-        daemon = PostmanDaemon(self.configfile)
-        daemon.port = 9100
-        p = multiprocessing.Process(target=daemon.run)
-        p.start()
-        # Add a delay here to allow the server to be fully started before
-        # starting to send requests from the client
-        time.sleep(1)
-
-        with self.assertRaises(ValueError):
-            mta = MTAClient(self.mailing_list, self.mta_configfile)
-            mta = MTAClient(self.member, self.mta_configfile)
-            mta = MTAClient(None, self.mta_configfile)
-        mta = MTAClient(self.mailing_list.address, self.mta_configfile)
-        self.assertTrue(isinstance(mta, MTAClient))
-        self.assertEqual(mta.address, self.mailing_list.address)
-        self.assertEqual(mta.suscriptors, self.mailing_list.members_addresses)
-        self.assertEqual(mta.reply_to, self.mailing_list.address)
-
-        p.terminate()
-
-    def test_get_raw_email(self):
-        # in order to start mta client instances, we need to have a postman
-        # daemon running on the background
-        # This should be added to the setUp() method, but then it would be
-        # more difficult to terminate the process after all the methods
-        # were called
-        daemon = PostmanDaemon(self.configfile)
-        daemon.port = 9100
-        p = multiprocessing.Process(target=daemon.run)
-        p.start()
-        # Add a delay here to allow the server to be fully started before
-        # starting to send requests from the client
-        time.sleep(1)
-
-        mta = MTAClient(self.mailing_list.address, self.mta_configfile)
-
-        sys_stdin = sys.stdin
-        sys.stdin = open(self.raw_email_file, 'r')
-        self.assertEqual(mta.get_raw_email(),
-                         self.raw_email)
-        sys.stdin.close()
-        with self.assertRaises(IOError):
-            mta.get_raw_email()
-
-        tmp_file= open(self.raw_email_file('r'))
-        raw_data = tmp_file.read()
-        tmp_file.close()
-        self.assertEqual(mta.get_raw_email(raw_data),
-                         self.raw_email)
-
-        p.terminate()
-
-    #def save_raw_email(self):
-    #    sys_stdin = sys.stdin
-    #    sys.stdin = open(self.raw_email_file, 'r')
-    #    self.mta.save_raw_email.filename = '/tmp/postman-test-mta-save-raw-email'
-    
-        
-        
-        
-            
-            
-        
Index: stman/tests/postman-mta.conf
===================================================================
--- postman/tests/postman-mta.conf	(revision 15)
+++ 	(revision )
@@ -1,13 +1,0 @@
-#
-# postman-mta.conf - Postman MTA client configuration file
-#
-
-[server]
-address = localhost
-port = 9100 # this port is hardcoded in tests/mta.py
-uri = http://%(address)s:%(port)s
-ssl = false
-
-[archive]
-persistent = true
-path = /tmp/postman-tests/mta/archive
Index: stman/tests/postman.conf
===================================================================
--- postman/tests/postman.conf	(revision 13)
+++ 	(revision )
@@ -1,31 +1,0 @@
-#
-# postman.conf - Postman configuration file
-#
-# IMPORTANT: This config file should be used only
-# for testing purposes
-
-[xmlrpc_server]
-address = localhost
-port = 9876
-ssl = false
-ssl_key = /usr/local/etc/postman/ssl/postman.key
-ssl_crt = /usr/local/etc/postman/ssl/postman.crt
-logfile = /tmp/postman-tests/xmlrpc_server.log
-
-[storage]
-backend = json
-path = /tmp/postman-tests/storage
-lists_db = %(path)s/mailings.%(backend)s
-members_db = %(path)s/members.%(backend)s
-
-[archive]
-enabled = true
-backend = json
-path = /tmp/postman-tests/archives
-
-[mailing_lists]
-private = true
-
-[members]
-auto_signup = false
-allow_chpasswd = false
Index: stman/tests/sample_raw_email.txt
===================================================================
--- postman/tests/sample_raw_email.txt	(revision 2)
+++ 	(revision )
@@ -1,179 +1,0 @@
-From root@fenrir.codigo23.lab Mon May 14 03:22:20 2012
-Return-Path: <root@fenrir.codigo23.lab>
-Received: from fenrir.codigo23.lab (localhost [127.0.0.1])
-	by fenrir.codigo23.lab (8.14.5/8.14.5) with ESMTP id q4D1MNxD038292
-	for <root@fenrir.codigo23.lab>; Sun, 13 May 2012 03:22:23 +0200 (CEST)
-	(envelope-from root@fenrir.codigo23.lab)
-Received: (from root@localhost)
-	by fenrir.codigo23.lab (8.14.5/8.14.5/Submit) id q4D1MNLp038270
-	for root; Sun, 13 May 2012 03:22:23 +0200 (CEST)
-	(envelope-from root)
-Date: Sun, 13 May 2012 03:22:23 +0200 (CEST)
-From: Charlie Root <root@fenrir.codigo23.lab>
-Message-Id: <201205130122.q4D1MNLp038270@fenrir.codigo23.lab>
-To: root@fenrir.codigo23.lab
-Subject: fenrir.codigo23.lab security run output
-
-
-Checking setuid files and devices:
-
-Checking for uids of 0:
-root 0
-toor 0
-
-Checking for passwordless accounts:
-
-Checking login.conf permissions:
-
-Checking for ports with mismatched checksums:
-
-fenrir.codigo23.lab kernel log messages:
-+++ /tmp/security.94lpgJ1k	2012-05-13 03:22:14.000000000 +0200
-+Accounting disabled
-+Accounting enabled
-+Accounting disabled
-+Accounting enabled
-
-fenrir.codigo23.lab login failures:
-
-fenrir.codigo23.lab refused connections:
-
-Checking for a current audit database:
-
-Database created: Sat May 12 03:20:04 CEST 2012
-
-Checking for packages with security vulnerabilities:
-
-Affected package: nvidia-driver-285.05.09
-Type of problem: NVIDIA UNIX driver -- access to arbitrary system memory.
-Reference: http://portaudit.FreeBSD.org/b91234e7-9a8b-11e1-b666-001636d274f3.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/94c0ac4f-9388-11e1-b242-00262d5ed8ee.html
-
-Affected package: firefox-8.0,1
-Type of problem: mozilla -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/380e8c56-8e32-11e1-9580-4061862b8c22.html
-
-Affected package: png-1.4.8
-Type of problem: png -- memory corruption/possible remote code execution.
-Reference: http://portaudit.FreeBSD.org/262b92fe-81c8-11e1-8899-001ec9578670.html
-
-Affected package: freetype2-2.4.7
-Type of problem: freetype -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/462e2d6c-8017-11e1-a571-bcaec565249c.html
-
-Affected package: mutt-devel-1.5.21_3
-Type of problem: mutt-devel -- failure to check SMTP TLS server certificate.
-Reference: http://portaudit.FreeBSD.org/49314321-7fd4-11e1-9582-001b2134ef46.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/057130e6-7f61-11e1-8a43-00262d5ed8ee.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/b8f0a391-7910-11e1-8a43-00262d5ed8ee.html
-
-Affected package: raptor2-2.0.4_1
-Type of problem: raptor/raptor2 -- XXE in RDF/XML File Interpretation.
-Reference: http://portaudit.FreeBSD.org/60f81af3-7690-11e1-9423-00235a5f2c9a.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/330106da-7406-11e1-a1d7-00262d5ed8ee.html
-
-Affected package: libtasn1-2.11
-Type of problem: libtasn1 -- ASN.1 length decoding vulnerability.
-Reference: http://portaudit.FreeBSD.org/2e7e9072-73a0-11e1-a883-001cc0a36e12.html
-
-Affected package: gnutls-2.12.14
-Type of problem: libtasn1 -- ASN.1 length decoding vulnerability.
-Reference: http://portaudit.FreeBSD.org/2e7e9072-73a0-11e1-a883-001cc0a36e12.html
-
-Affected package: gnutls-2.12.14
-Type of problem: gnutls -- possible overflow/Denial of service vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/aecee357-739e-11e1-a883-001cc0a36e12.html
-
-Affected package: firefox-8.0,1
-Type of problem: mozilla -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/a1050b8b-6db3-11e1-8b37-0011856a6e37.html
-
-Affected package: portaudit-0.5.17
-Type of problem: portaudit -- auditfile remote code execution.
-Reference: http://portaudit.FreeBSD.org/6d329b64-6bbb-11e1-9166-001e4f0fb9b1.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- Errant plug-in load and GPU process memory corruption.
-Reference: http://portaudit.FreeBSD.org/ab1f515d-6b69-11e1-8288-00262d5ed8ee.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- cross-site scripting vulnerability.
-Reference: http://portaudit.FreeBSD.org/1015e1fe-69ce-11e1-8288-00262d5ed8ee.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/99aef698-66ed-11e1-8288-00262d5ed8ee.html
-
-Affected package: postgresql-client-8.4.10
-Type of problem: databases/postgresql*-client -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/174b8864-6237-11e1-be18-14dae938ec40.html
-
-Affected package: libxml2-2.7.8_1
-Type of problem: libxml2 -- heap buffer overflow.
-Reference: http://portaudit.FreeBSD.org/57f1a624-6197-11e1-b98c-bcaec565249c.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/2f5ff968-5829-11e1-8288-00262d5ed8ee.html
-
-Affected package: python24-2.4.5_8
-Type of problem: Python -- DoS via malformed XML-RPC / HTTP POST request.
-Reference: http://portaudit.FreeBSD.org/b4f8be9e-56b2-11e1-9fb7-003067b2972c.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/fe1976c2-5317-11e1-9e99-00262d5ed8ee.html
-
-Affected package: firefox-8.0,1
-Type of problem: mozilla -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/0a9e2b72-4cb7-11e1-9146-14dae9ebcf89.html
-
-Affected package: sudo-1.8.3_1
-Type of problem: sudo -- format string vulnerability.
-Reference: http://portaudit.FreeBSD.org/7c920bb7-4b5f-11e1-9f47-00e0815b8da8.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/33d73d59-4677-11e1-88cd-00262d5ed8ee.html
-
-Affected package: wireshark-1.6.2
-Type of problem: Wireshark -- Multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/3ebb2dc8-4609-11e1-9f47-00e0815b8da8.html
-
-Affected package: ffmpeg-0.7.8,1
-Type of problem: ffmpeg -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/ea2ddc49-3e8e-11e1-8095-5404a67eef98.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/1a1aef8e-3894-11e1-8b5c-00262d5ed8ee.html
-
-Affected package: firefox-8.0,1
-Type of problem: mozilla -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/e3ff776b-2ba6-11e1-93c6-0011856a6e37.html
-
-Affected package: chromium-15.0.874.121
-Type of problem: chromium -- multiple vulnerabilities.
-Reference: http://portaudit.FreeBSD.org/68ac6266-25c3-11e1-b63a-00262d5ed8ee.html
-
-Affected package: libXfont-1.4.4,1
-Type of problem: libXfont -- possible local privilege escalation.
-Reference: http://portaudit.FreeBSD.org/304409c3-c3ef-11e0-8aa5-485d60cb5385.html
-
-32 problem(s) in your installed packages found.
-
-You are advised to update or deinstall the affected package(s) immediately.
-
--- End of security output --
Index: stman/tools.py
===================================================================
--- postman/tools.py	(revision 11)
+++ 	(revision )
@@ -1,34 +1,0 @@
-# -*- coding: utf-8 -*-
-
-"""
-The postman project - tools.py
-
-This file is released under the BSD license, see LICENSE for
-more information.
-
-Francisco de Borja Lopez Rio - <borja@codigo23.net>
-Soluciones Informaticas Codigo23 S.L.U. - http://codigo23.net
-"""
-
-import re
-
-def validate_email_address(address):
-
-    """
-    This function validates a given address, returning True
-    if it is a valid address, False otherwise.
-
-    The function uses a regexp from the django project, and
-    it is inspired in this snippet:
-
-    http://djangosnippets.org/snippets/1093/
-    """
-
-    if not isinstance(address, str):
-        return False
-
-    email_re = re.compile(
-    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*"  # dot-atom
-    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string
-    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE)  # domain
-    return True if email_re.match(address) else False
Index: setup.py
===================================================================
--- setup.py	(revision 15)
+++ setup.py	(revision 16)
@@ -14,16 +14,16 @@
 
 setup(
-    name='postman',
+    name='mailjam',
     version='0.1.0',
     author='Francisco de Borja Lopez Rio',
     author_email='borja@codigo23.net',
-    packages=['postman'],
-    url='https://bitbucket.org/codigo23/postman',
+    packages=['mailjam'],
+    url='https://bitbucket.org/codigo23/mailjam',
     license='BSD licence, see LICENCE',
     description='Mailing lists management software',
     long_description=open('README').read(),
-    scripts=['bin/postman-server', 'bin/postman-mta'],
-    #data_files=[(proper_etc_path()+'postman', ['conf/postman.conf',
-    #                                           'conf/postman-mta.conf']),
+    scripts=['bin/mailjam-server', 'bin/mailjam-mta'],
+    #data_files=[(proper_etc_path()+'mailjam', ['conf/mailjam.conf',
+    #                                           'conf/mailjam-mta.conf']),
     #            ]
 )
