Tiny documenatation improvement.
[breadcrumb.git] / code / runserver.py
blob3d4385bbc78f1889976b45aef05ce5017a8d650b
1 #!/usr/bin/env python
2 # -*- coding: utf8 -*-
3 """A script for starting a Breadcrumb server."""
5 # Copyright (C) 2008 Laurens Van Houtven <lvh at laurensvh.be>
6 # This program is free software: you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation, either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 import os
20 import sys
21 import logging
23 import optparse
24 import ConfigParser
26 import breadcrumb.server.net as net
27 import breadcrumb.server.handlers.base as base
28 import breadcrumb.common.consts as consts
29 from breadcrumb.common.loggingtools import get_logging_level
31 def main():
32 """ Starts the default Breadcrumb server. """
33 config = find_configuration()
34 serverargs = get_serverargs(config)
36 if 'verbosity' in serverargs:
37 logger.setLevel(get_logging_level(serverargs['verbosity']))
39 if 'pythonpath' in serverargs:
40 sys.path.append(os.path.abspath(serverargs['pythonpath']))
41 del serverargs['pythonpath']
43 handler = parse_handlers(config)
45 net.start_server(handler = handler, **serverargs)
47 def find_configuration(filename = None):
48 """Tries to find and parse a server configuration file.
50 Returns a ConfigParser object."""
51 config = ConfigParser.ConfigParser()
53 filenames = filter(None, consts.SERVER_CONFIG_FILENAMES + [filename])
54 for filename in filenames:
55 try:
56 filename = os.path.expanduser(filename)
57 config.readfp(open(filename))
58 logger.info("Using config file %s..." % filename)
59 return config
60 except NameError:
61 logger.debug("No config file at %s..." % filename)
62 continue
64 logger.warning("No usable config files found!")
66 def parse_handlers(config):
67 """Parses the handlers described in the configuration file.
69 Returns a sequential handler with all the (correctly configured) handlers
70 from the configuration file.
71 """
72 seqhandler = base.SequentialHandler(name = "sequential")
74 for name in config.sections():
75 if name == "server":
76 continue
78 logger.debug("Found new handler section (name: %s)..." % name)
80 data = dict(config.items(name) + [['name', name]])
82 if 'class' not in data:
83 logger.error(
84 'No class specified for handler section %s, skipping...' % name)
85 continue
87 splitnames = data['class'].split('.')
88 del data['class']
89 modulename, classname = '.'.join(splitnames[:-1]), splitnames[-1]
91 if 'pythonpath' in data:
92 logger.debug("Extra path specified, adding to sys.path...")
93 sys.path.append(data['pythonpath'])
94 del data['pythonpath']
96 try:
97 __import__(modulename, globals(), locals(), [classname])
98 except ImportError:
99 logger.error("Couldn't import %s, skipping..." % modulename)
100 continue
102 handler_class = getattr(sys.modules[modulename], classname)
104 logger.debug("Creating handler with args: %s" % repr(data))
105 handler = handler_class(**data)
107 seqhandler.add_handler(handler)
109 return seqhandler
111 def get_serverargs(config):
112 """Gets the server arguments from the ConfigParser object.
114 Returns a dict.
116 if not config.has_section('server'):
117 logger.info("Config file doesn't have a [server] section...")
118 return {}
120 return dict(config.items('server'))
122 if __name__ == "__main__":
123 logging.basicConfig(level=logging.INFO)
124 logger = logging.getLogger("Breadcrumb.Scripts.runserver")
125 main()