/
config.py
204 lines (149 loc) · 5.61 KB
/
config.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
"""
This module loads a configuration file and setup basic logging.
This is a light weight suitable for import from unit testing.
Import this module as the first application module.
"""
import ConfigParser
import logging, logging.handlers
import os
import os.path
import StringIO
import sys
# This is intended to synchronize with the CONFIG_FILE edited by user.
# This can be a hardcoded fallback in case user has mess up the file.
# Note: Keep the setting below to put test log is its own directory
# logs=testlogs, archive=testdata/archive, etc
SYSTEM_DEFAULT_CONFIG="""
[path]
archive=testdata/archive
archiveindex=testdata/archive/index
docBase=lib/htdocs
testDoc=lib/testdocs
logs=testlogs
[http]
proxy_port=8051
proxy_threads=10
admin_port=8050
http_proxy=
[messagelog]
max_messagelog=2048
maxuri=1024
mlog=
[indexing]
interval=3
numDoc=50
max_interval=360
archive_interval=1
[filter]
domain.0=.googlesyndication.com
domain.1=
domain.2=
domain.3=
domain.4=
[version]
number=0.4.2
created=2005-02-21
copyright=2005
"""
APPLICATION_NAME = 'MindRetrieve'
### logging ############################################################
bootstrapHdlr = None
def setupLogging():
""" Setup a bootstrap logging to console """
# why do we need to setup a bootstrap logger?
# Can't logging send to console by default?
global bootstrapHdlr
bootstrapHdlr = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter('%(asctime)s %(name)-10s - %(message)s')
bootstrapHdlr.setFormatter(formatter)
rootlog = logging.getLogger()
rootlog.addHandler(bootstrapHdlr)
rootlog.setLevel(logging.DEBUG)
setupLogging()
### config file ########################################################
class Config(object):
""" Provides a default config; setup paths """
def __init__(self):
""" initialize with default config file """
self.cparser = ConfigParser.ConfigParser()
self.cparser.readfp( StringIO.StringIO(SYSTEM_DEFAULT_CONFIG), 'System Default')
self.application_name = '%s %s' % (APPLICATION_NAME, self.get('version', 'number', '?'))
def load(self, pathname):
""" Load a configuration file. Intended to be called only once. """
logging.getLogger().info('Loading config file: %s', pathname)
# ConfigParser.read() do nothing if name does not exist. Check first.
if not os.path.exists(pathname):
logging.getLogger().error('Config file does not exist: %s', pathname)
else:
self.pathname = pathname
self.cparser.read(pathname)
def setupPaths(self):
""" Create directories specified in [path] """
self._setupPath(self.getPath('logs'))
self._setupPath(self.getPath('archive'))
def _setupPath(self, path):
""" create directory if not already exists """
if os.path.isdir(path): return
try:
# raise exception if path exist but is not a directory
os.makedirs(path)
except OSError, e:
raise OSError, 'Unable to create directory specified in %s\n%s' % (self.pathname, e)
def get(self, section, name, default=None):
try:
return self.cparser.get(section, name)
except Exception, e:
if default != None: return default
raise e
def getint(self, section, name, default=None):
try:
return self.cparser.getint(section, name)
except Exception, e:
if default != None: return default
raise e
def getboolean(self, section, name, default=None):
try:
return self.cparser.getboolean(section, name)
except Exception, e:
if default != None: return default
raise e
def getPath(self, name, default='.'):
""" helper to get config from path section """
return self.get('path', name, default)
def set(self, section, option, value):
self.cparser.set(section, option, value)
def dump(self, out):
out.write('Config object: %s\n' % str(self.cparser))
for s in self.cparser.sections():
out.write('Section: %s\n' % s)
for name, value in self.cparser.items(s):
out.write(' %s=%s\n' % (name,value))
cfg = Config()
### testing ############################################################
import unittest
TEST_FILENAME = 'config.ini'
class TestConfig(unittest.TestCase):
def setUp(self):
# save cfg which would get modified in testConfig
global cfg
self.cfg0 = cfg
cfg = Config()
def testConfig(self):
print '\n@testConfig:', TEST_FILENAME
cfg.load(TEST_FILENAME)
cfg.setupPaths()
cfg.dump(sys.stdout)
self.assert_( cfg.get('version','created').find('2005') >= 0)
def testDefault(self):
self.assertNotEqual( cfg.get('version','created','X'), 'X') # not using default
self.assertEqual( cfg.get('version','keyX', 'default'), 'default')
self.assertEqual( cfg.get('version','keyX', '' ), '') # Test out default of ''
self.assertEqual( cfg.getint ('version','keyX', 1 ), 1)
self.assertEqual( cfg.getint ('version','keyX', 0 ), 0) # Test out default of 0
self.assertEqual( cfg.getboolean('version','keyX', True ), True )
self.assertEqual( cfg.getboolean('version','keyX', False ), False) # Test out default of False
def tearDown(self):
global cfg
cfg = self.cfg0
if __name__ == '__main__':
unittest.main()