Added versioning support
[breadcrumb.git] / code / runserver.py
blob5774b844f3daee807ec1b952fb481f23936ee03a
1 #!/usr/bin/env python
2 # -*- coding: utf8 -*-
3 """ Runs the UDP server for Breadcrumb. """
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
30 def main():
31 """ Starts the default Breadcrumb server. """
32 config = find_configuration()
34 handler = parse_handlers(config)
35 serverargs = get_serverargs(config)
37 set_verbosity(serverargs)
39 net.start_server(handler = handler, **serverargs)
41 def find_configuration(filename = None):
42 """
43 Tries to find and parse a server configuration file.
45 Returns a ConfigParser object.
46 """
47 config = ConfigParser.ConfigParser()
49 filenames = filter(None, consts.SERVER_CONFIG_FILENAMES + [filename])
50 for filename in filenames:
51 try:
52 filename = os.path.expanduser(filename)
53 config.readfp(open(filename))
54 logging.info("Using config file %s..." % filename)
55 return config
56 except NameError:
57 logging.debug("No config file at %s..." % filename)
58 continue
60 logging.warning("No usable config files found!")
62 def set_verbosity(serverargs):
63 """Sets the logging level, based on the server's arguments."""
64 if 'verbosity' in serverargs:
65 verbosity = serverargs['verbosity'].lower()
67 if verbosity in ['high', 'loud', 'debug']:
68 logging.getLogger().setLevel(logging.DEBUG)
69 elif verbosity in ['low', 'quiet', 'error']:
70 logging.getLogger().setLevel(logging.ERROR)
71 elif verbosity in ['verylow', 'veryquiet', 'critical']:
72 logging.getLogger().setLevel(logging.CRITICAL)
73 else:
74 logging.getLogger().setLevel(logging.INFO)
76 del serverargs['verbosity']
78 logging.getLogger().setLevel(logging.INFO)
80 def parse_handlers(config):
81 """
82 Parses the handlers described in the configuration file.
84 Returns a sequential handler with all the (correctly configured) handlers
85 from the configuration file.
86 """
87 seqhandler = base.SequentialHandler()
89 for name in config.sections():
90 if name == "server":
91 continue
93 data = dict(config.items(name))
95 if 'class' not in data:
96 logging.error('No class for %s, skipping...' % name)
97 continue
99 splitnames = data['class'].split('.')
100 del data['class']
101 modulename, classname = '.'.join(splitnames[:-1]), splitnames[-1]
103 if 'pythonpath' in data:
104 sys.path.append(data['pythonpath'])
105 del data['pythonpath']
107 try:
108 __import__(modulename, globals(), locals(), [classname])
109 except ImportError:
110 logging.error("Couldn't import %s, skipping..." % modulename)
111 continue
113 handlerclass = getattr(sys.modules[modulename], classname)
115 logging.debug("Creating handler with args: %s" % repr(data))
116 handler = handlerclass(**data)
118 seqhandler.addhandler(handler)
120 return seqhandler
122 def get_serverargs(config):
124 Gets the server arguments from the ConfigParser object.
126 Returns a dict.
128 if not config.has_section('server'):
129 logging.info("Config file doesn't have a [server] section...")
130 return {}
132 return dict(config.items('server'))
134 if __name__ == "__main__":
135 main()