initial commit
[synarere.git] / core / confparse.py
blobc68a415eaa420215fc06a2f6f64d5679dca4c36c
1 # synarere -- a highly modular and stable IRC bot.
2 # Copyright (C) 2010 Michael Rodriguez.
3 # Rights to this code are documented in docs/LICENSE.
5 '''Configuration parser.'''
7 # Import required Python module.
8 import os
10 # Import required source modules.
11 import logger, irc, var
13 class Exception(Exception):
14 pass
16 class ConfigBlock(object):
17 def __init__ (self, label, values={}):
18 self.label = label
19 self.vars = {}
21 # Copy over any values given during initialization
22 for key in values:
23 self.vars[key] = values[key]
25 def add (self, name, value):
26 self.vars[name] = value
28 def get (self, name, defval=None):
29 return self.vars.get(name, defval)
31 class ConfigParser:
32 def __init__(self, file):
33 self.file = file
34 self.parse()
36 def rehash(self, on_sighup):
37 '''Rehash configuration and change synarere to fit the new conditions.'''
39 logger.info('Rehashing configuration %s' % ('due to SIGHUP.' if on_sighup else ''))
40 self.parse()
42 def parse(self):
43 '''Parse our file, and put the data into a dictionary.'''
45 lno = 0
47 # Attempt to open the file.
48 try:
49 fh = open(self.file, 'r')
50 except IOError, e:
51 raise Exception(os.strerror(e.args[0]))
53 # Parse.
54 self.blocks = []
56 for line in fh.xreadlines():
57 for cno, c in enumerate(line):
58 if c == '\n':
59 # Increment the line number.
60 lno += 1
62 if c == '#': # Comment until EOL.
63 break
64 if c == ':': # Block label.
65 label = line[: cno].strip()
66 self.blocks.append(ConfigBlock(label))
67 if c == '=': # Variable.
68 if not self.blocks: # Skip this line, as no block label was given yet.
69 break
70 varname = line[:cno].strip()
71 varval = line[cno + 1:].strip()
72 self.blocks[-1].add(varname, varval)
73 break
75 # Close the file handle
76 fh.close()
78 def xget(self, block, variable=None):
79 '''
80 Return whatever is in block:variable. If variable is None,
81 we will iterate over mutiple blocks, thus allowing us to
82 return multiple values from multiple blocks.
83 '''
85 if block not in set(b.label for b in self.blocks):
86 raise Exception('Block %s not found.' % block)
88 for i in self.blocks:
89 if i.label == block:
90 if variable is None: # Just get blocks by this name
91 yield i
92 else: # Get a member of blocks by this name.
93 yield i.get(variable)
95 def get(self, block, variable=None):
96 '''
97 Call our iterating generator (xget) and just store all its
98 results into a list to return all at once.
99 '''
101 return [b for b in self.xget(block, variable)]