PageRenderTime 316ms CodeModel.GetById 121ms app.highlight 73ms RepoModel.GetById 120ms app.codeStats 0ms

/silverlining/commands/create_config.py

https://bitbucket.org/ianb/silverlining/
Python | 111 lines | 101 code | 8 blank | 2 comment | 42 complexity | 98da81da3317058fa6d5877fe903f252 MD5 | raw file
  1"""Clear all the data from an application instance"""
  2import os
  3import re
  4import shutil
  5from cmdutils import CommandError
  6import tempita
  7from silversupport.appconfig import AppConfig
  8from silversupport.util import read_config
  9
 10def command_create_config(config):
 11    app = AppConfig(os.path.join(config.args.dir, 'app.ini'))
 12    settings = os.path.join(app.config_template, 'template.ini')
 13    if not os.path.exists(settings):
 14        settings = {}
 15    else:
 16        settings = read_config(settings)
 17    if not app.config_template:
 18        config.logger.fatal('The application has no config.template')
 19        return 1
 20    if config.args.info:
 21        return show_info(config, app, settings)
 22    variables = {}
 23    for expr in config.args.variable:
 24        if '=' not in expr:
 25            raise CommandError(
 26                'The argument %s should be in the form var=value' % expr)
 27        var_name, value = expr.split('=', 1)
 28        variables[var_name] = value
 29    for var_name, desc in sorted(settings.get('variables', {}).items()):
 30        if var_name in variables:
 31            continue
 32        value = raw_input('%s (%s): ' % (var_name, desc))
 33        variables[var_name] = value
 34    fill_directory(app.config_template,
 35                   config.args.output,
 36                   variables,
 37                   skip_files='./template.ini')
 38
 39def show_info(config, app, settings):
 40    l = config.logger
 41    if not settings:
 42        l.notify('The application has no template.ini in %s' % app.config_template)
 43        return
 44    l.notify('The variables that can be substituted in the files:')
 45    for v, desc in sorted(settings.get('variables', {}).items()):
 46        l.notify('  %s:' % v)
 47        ## FIXME: wrap better:
 48        l.notify('    %s' % desc)
 49
 50def fill_directory(source, dest, variables, skip_files=()):
 51    variables.setdefault('dot', '.')
 52    source = os.path.abspath(source)
 53    for dirpath, dirnames, filenames in os.walk(source):
 54        for dirname in list(dirnames):
 55            if dirname in skip_files:
 56                dirnames.remove(dirname)
 57        for filename in list(filenames):
 58            if filename in skip_files:
 59                filenames.remove(filename)
 60        for filename in filenames:
 61            if filename.startswith('.'):
 62                continue
 63            source_filename = os.path.join(dirpath, filename)
 64            assert source_filename.startswith(source)
 65            path = source_filename[len(source):].lstrip('/')
 66            path = render_filename(path, variables)
 67            is_template = filename.endswith('.tmpl')
 68            dest_filename = os.path.join(dest, path)
 69            if is_template:
 70                dest_filename = dest_filename[:-5]
 71            dest_dir = os.path.dirname(dest_filename)
 72            if not os.path.exists(dest_dir):
 73                os.makedirs(dest_dir)
 74            if is_template:
 75                source_content = render_source(source_filename, variables)
 76            else:
 77                source_content = file_content(source_filename)
 78            if os.path.exists(dest_filename):
 79                if file_content(dest_filename) == source_content:
 80                    continue
 81                backup_file(dest_filename)
 82            fp = open(dest_filename, 'wb')
 83            fp.write(source_content)
 84
 85_var_re = re.compile(r'\+(.*?)\+')
 86
 87def render_filename(path, variables):
 88    return _var_re.sub(lambda m: variables[m.group(1)], path)
 89
 90def render_source(filename, variables):
 91    if os.path.splitext(filename)[1].lower() in ('.html', '.htm'):
 92        TemplateClass = tempita.HTMLTemplate
 93    else:
 94        TemplateClass = tempita.Template
 95    template = TemplateClass.from_filename(filename)
 96    return template.substitute(variables)
 97
 98def file_content(filename):
 99    fp = open(filename, 'rb')
100    c = fp.read()
101    fp.close()
102    return c
103
104def backup_file(filename):
105    n = 1
106    while 1:
107        new_fn = '%s.%s' % (filename, n)
108        if not os.path.exists(new_fn):
109            break
110        n += 1
111    shutil.copyfile(filename, new_fn)