172 lines
4.9 KiB
Python
172 lines
4.9 KiB
Python
#!/usr/bin/env python
|
|
# vim: set expandtab:
|
|
"""
|
|
Parse Asterisk configuration files.
|
|
|
|
This module provides parsing functionality for asterisk config files.
|
|
|
|
import asterisk.config
|
|
import sys
|
|
|
|
# load and parse the config file
|
|
try:
|
|
config = asterisk.config.Config('/etc/asterisk/extensions.conf')
|
|
except asterisk.config.ParseError, (line, reason):
|
|
print "Parse Error line: %s: %s" % (line, reason)
|
|
sys.exit(1)
|
|
except IOError, reason:
|
|
print "Error opening file: %s" % reason
|
|
sys.exit(1)
|
|
|
|
# print our parsed output
|
|
for category in config.categories:
|
|
print '[%s]' % category.name # print the current category
|
|
|
|
for item in category.items:
|
|
print ' %s = %s' % (item.name, item.value)
|
|
"""
|
|
|
|
import sys
|
|
|
|
|
|
class ParseError(Exception):
|
|
pass
|
|
|
|
|
|
class Line(object):
|
|
def __init__(self, line, number):
|
|
self.line = ''
|
|
self.comment = ''
|
|
line = line.strip() # I guess we don't preserve indentation
|
|
self.number = number
|
|
parts = line.split(';')
|
|
if len(parts) >= 2:
|
|
self.line = parts[0].strip()
|
|
self.comment = ';'.join(
|
|
parts[1:]) # Just in case the comment contained ';'
|
|
else:
|
|
self.line = line
|
|
|
|
def __str__(self):
|
|
return self.get_line()
|
|
|
|
def get_line(self):
|
|
if self.comment and self.line:
|
|
return '%s\t;%s' % (self.line, self.comment)
|
|
elif self.comment and not self.line:
|
|
return ';%s' % self.comment
|
|
return self.line
|
|
|
|
|
|
class Category(Line):
|
|
def __init__(self, line='', num=-1, name=None):
|
|
Line.__init__(self, line, num)
|
|
if self.line:
|
|
if (self.line[0] != '[' or self.line[-1] != ']'):
|
|
raise ParseError(
|
|
self.number, "Missing '[' or ']' in category definition")
|
|
self.name = self.line[1:-1]
|
|
elif name:
|
|
self.name = name
|
|
else:
|
|
raise Exception(
|
|
"Must provide name or line representing a category")
|
|
|
|
self.items = []
|
|
self.comments = []
|
|
|
|
def get_line(self):
|
|
if self.comment:
|
|
return '[%s]\t;%s' % (self.name, self.comment)
|
|
return '[%s]' % self.name
|
|
|
|
def append(self, item):
|
|
self.items.append(item)
|
|
|
|
def insert(self, index, item):
|
|
self.items.insert(index, item)
|
|
|
|
def pop(self, index=-1):
|
|
self.items.pop(index)
|
|
|
|
def remove(self, item):
|
|
self.items.remove(item)
|
|
|
|
|
|
class Item(Line):
|
|
def __init__(self, line='', num=-1, name=None, value=None):
|
|
Line.__init__(self, line, num)
|
|
self.style = ''
|
|
if self.line:
|
|
self.parse()
|
|
elif (name and value):
|
|
self.name = name
|
|
self.value = value
|
|
else:
|
|
raise Exception("Must provide name or value representing an item")
|
|
|
|
def parse(self):
|
|
try:
|
|
name, value = self.line.split('=', 1)
|
|
except ValueError:
|
|
if self.line.strip()[-1] == ']':
|
|
raise ParseError(self.number, "Category name missing '['")
|
|
else:
|
|
raise ParseError(
|
|
self.number, "Item must be in name = value pairs")
|
|
|
|
if value and value[0] == '>':
|
|
self.style = '>' # preserve the style of the original
|
|
value = value[1:].strip()
|
|
self.name = name.strip()
|
|
self.value = value
|
|
|
|
def get_line(self):
|
|
if self.comment:
|
|
return '%s =%s %s\t;%s' % (self.name, self.style, self.value, self.comment)
|
|
return '%s =%s %s' % (self.name, self.style, self.value)
|
|
|
|
|
|
class Config(object):
|
|
def __init__(self, filename):
|
|
self.filename = filename
|
|
self.raw_lines = [] # Holds the raw strings
|
|
self.lines = [] # Holds things in order
|
|
self.categories = []
|
|
|
|
# load and parse the file
|
|
self.load()
|
|
self.parse()
|
|
|
|
def load(self):
|
|
self.raw_lines = open(self.filename).readlines()
|
|
#try:
|
|
#self.raw_lines = open(self.filename).readlines()
|
|
#except IOError:
|
|
#sys.stderr.write('WARNING: error opening filename: %s No data read. Starting new file?' % self.filename)
|
|
#self.raw_lines = []
|
|
|
|
def parse(self):
|
|
cat = None
|
|
num = 0
|
|
for line in self.raw_lines:
|
|
num += 1
|
|
line = line.strip()
|
|
if not line or line[0] == ';':
|
|
item = Line(line or '', num)
|
|
self.lines.append(item)
|
|
if cat:
|
|
cat.comments.append(item)
|
|
continue
|
|
elif line[0] == '[':
|
|
cat = Category(line, num)
|
|
self.lines.append(cat)
|
|
self.categories.append(cat)
|
|
continue
|
|
else:
|
|
item = Item(line, num)
|
|
self.lines.append(item)
|
|
if cat:
|
|
cat.append(item)
|
|
continue
|