PageRenderTime 33ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 0ms

/silverlining/commands/create_config.py

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