#!/usr/bin/env python ''' Asterisk and Digium phone config generator for Makers Local 256 ''' import pystache import json import hashlib import argparse import os import errno def render_write(path, config, template, model): '''Render the template and write to the specified file''' renderer = pystache.Renderer() rendered_data = renderer.render_path(template, model) out = open('%s/%s' % (path, config), 'w') out.write(rendered_data) out.close() return rendered_data def mkdir_p(path): '''Enable 'mkdir -p'-like functionality''' try: os.makedirs(path) except OSError as exc: if exc.errno == errno.EEXIST and os.path.isdir(path): pass else: raise def main(): '''Generate all configs for Asterisk and for phones''' # parse the provided options (if any) args_parser = argparse.ArgumentParser( description='Generate ML256 phone configs') args_parser.add_argument('--model', '-m', dest='model', default='phones.json', type=argparse.FileType('r')) configs = args_parser.parse_args() # load the phone data model = json.load(configs.model) # set path defaults model_defaults = { 'ast_config_path': '/etc/asterisk/', 'ast_static_path': '/var/lib/asterisk/static-http/config/', 'register': '1', 'http_static_path': 'http://asterisk:8088/static/config/' } for key, default in model_defaults.iteritems(): if key not in model: model[key] = default # ensure that requisite directories exist mkdir_p(model['ast_config_path']) mkdir_p(model['ast_static_path']) # render the sip config render_write(model['ast_config_path'], 'phones-sip.conf', 'phones-sip.conf.mustache', model) # set index for contacts and accumulate shop-wide dialstring i = 0 dial_accum = [] for phone in model['phones']: # set the indexes for writing out contacts phone['index'] = i i = i + 1 dial_accum.append('SIP/' + phone['user']) model['all_phones_dial'] = '&'.join(dial_accum) # render the extensions config render_write(model['ast_config_path'], 'extensions.conf', 'extensions.conf.mustache', model) # render the contacts config contacts_data = render_write(model['ast_static_path'], 'contacts.xml', 'contacts.xml.mustache', model) model['contacts_md5'] = hashlib.md5(contacts_data.encode()).hexdigest() # render the BLF config render_write(model['ast_static_path'], 'blf.xml', 'blf.xml.mustache', model) # add a default config model['phones'].append({ 'user':'anonymous', 'name':'Unconfigured Phone', 'number':'anonymous', 'register':'0', 'mac':'000000000000' }) # render the phone configs for phone in model['phones']: # overlay the phone config on a shallow clone of the model local_model = model.copy() local_model.update(phone) # render the individual phone config render_write(local_model['ast_static_path'], '%s.cfg' % (local_model['mac']), 'phone.cfg.mustache', local_model) main()