Changeset 6:2a0f6f8cbc52 in mailjam


Ignore:
Timestamp:
May 18, 2012, 12:59:55 PM (10 years ago)
Author:
Francisco de Borja Lopez Rio <borja@…>
Branch:
default
Phase:
public
Message:

Added an initial version of the code that will handle the XMLRPC interface
of the server.

Added a script to start the server (not fully functional yet)

Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • postman/daemon.py

    r5 r6  
    11# -*- coding: utf-8 -*-
    22
    3 import os
     3import os, inspect, logging
     4from SimpleXMLRPCServer import SimpleXMLRPCServer, list_public_methods
    45
    56from postman import config
     
    3637        """
    3738        if self.mailings:
    38             # Save the config file from where we can reload information about the
    39             # mailing lists managed by this postman instance
     39            # Save the config file from where we can reload information about
     40            # the mailing lists managed by this postman instance
    4041            self.dbs['mailings'].write(self.mailings_addresses)
    4142            # Save each mailing list data into its separated persistence file
     
    132133            self.save()
    133134        return added
    134        
    135 
    136 
    137 
    138 
    139 
    140 
     135
     136
     137class PostmanXMLRPC():
     138    """
     139    This class is a wrapper we will use to limit the methods that will be
     140    published through the XMLRPC link. Only the methods from this class
     141    will be available through that link.
     142
     143    As we use dotted names to separate xmlrpc-exported methods into different
     144    namespaces, this class contains nothing, it will be used only for
     145    method-registering purposes. The MailingListXMLRPC and MemberXMLRPC classes
     146    contain the actual methods that are published.
     147
     148    More information on this approach here:
     149
     150    http://www.doughellmann.com/PyMOTW/SimpleXMLRPCServer/#exposing-methods-of-objects
     151    """
     152
     153    def _listMethods(self):
     154        return list_public_methods(self)
     155
     156    def _methodHelp(self, method):
     157        f = getattr(self, method)
     158        return inspect.getdoc(f)
     159
     160
     161class MailingListXMLRPC():
     162    def __init__(self):
     163        self.postman = Postman()
     164        self.postman.load()
     165    def add(self, info={}):
     166        self.postman.add_mailing_list(info)
     167
     168
     169class MemberXMLRPC():
     170    def __init__(self):
     171        self.postman = Postman()
     172        self.postman.load()
     173    def add(self, member_addr=None, list_addr=None):
     174        self.postman.add_mailing_member(member_addr, list_addr)
     175                 
     176
     177class PostmanDaemon():
     178    def __init__(self, configfile=None):
     179        if not configfile:
     180            # FIXME: This is not used right now, we are getting the stuff
     181            # from postman.config, but we will move configurations to a
     182            # external ini-style config file soon
     183            configfile = os.path.join(os.path.dirname(__file__),
     184                                      '../conf/postman.conf')
     185        self.configfile = configfile
     186
     187        self.logfile = os.path.join(os.path.dirname(__file__), 'server.log')
     188        logging.basicConfig(filename=self.logfile, level=logging.DEBUG)
     189
     190        self.server = None
     191        self.ready_to_serve = False
     192       
     193    def create_server(self):
     194        """
     195        If there is no server initialized in self.server, create an instance
     196        of SimpleXMLRPCServer in that attribute. If there is already a server
     197        initialized there, simply return True
     198        """
     199        address='localhost'
     200        port = 9000       
     201        if not self.server:
     202            msg = 'Creating XMLRPC server object on {}:{}'.format(address,port)
     203            logging.info(msg)
     204            self.server = SimpleXMLRPCServer((address, port), allow_none=True,
     205                                             logRequests=True)
     206            self.server.register_introspection_functions()
     207        return True
     208
     209    def add_methods(self):
     210        """
     211        Check if there is an initialized server (initialize it if there is none)
     212        and then register all the Postman public methods to be served through
     213        the xml-rpc link
     214
     215        Once the methods are registered set self.ready_to_serve to True       
     216        """
     217        if not self.server:
     218            # ensure there is an XMLRPC server initialized
     219            self.create_server()
     220        msg = 'Registering public methods'
     221        logging.info(msg)
     222        root = PostmanXMLRPC()
     223        root.lists = MailingListXMLRPC()
     224        root.members = MemberXMLRPC()
     225        self.server.register_instance(root, allow_dotted_names=True)
     226        self.ready_to_serve = True
     227           
     228    def run(self):
     229        """
     230        Run the xmlrpc daemon. If self.ready_to_serve is False, call
     231        self.add_methods, which will initialize the server and will register all
     232        the public methods into that server
     233        """
     234        if not self.ready_to_serve:
     235            self.add_methods()
     236        msg = 'Starting XMLRPC server on {}:{}'.format(address,port)
     237        logging.info(msg)
     238        self.server.serve_forever()
  • postman/tests/daemon.py

    r5 r6  
    11# -*- coding: utf-8 -*-
    22
    3 import os
     3import os, xmlrpclib
    44from unittest import TestCase
    55from postman.daemon import Postman
     
    121121        # Clear the files created by the tests
    122122        postman.clear()
     123
     124
     125class TestPostmanDaemon(TestCase):
     126    """
     127    postman.daemon.PostmanDaemon tests.
     128   
     129    """
     130    def setUp(self):
     131        config = {'private': False, 'archive': '/tmp/postman-tests/archive',
     132                  'storage': '/tmp/postman-tests/storage'}
     133        self.mailing_list = MailingList('test_xmlrpc', 'test_xmlrpc@example.com',
     134                                        members={}, config=config)
     135        self.member =  Member('test@example.com')
     136        # FIXME: Hardcoded url here, should be picked from a config file
     137       
     138        self.link = xmlrpclib.ServerProxy('http://localhost:9000')
Note: See TracChangeset for help on using the changeset viewer.