Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1f042e1
commit f16ba47
Showing
3 changed files
with
127 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,7 +10,6 @@ dist | |
build | ||
eggs | ||
parts | ||
bin | ||
var | ||
sdist | ||
develop-eggs | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#!/usr/bin/env python | ||
import os | ||
import sys | ||
from optparse import OptionParser | ||
|
||
from pymtt import PyMTT | ||
|
||
if __name__ == '__main__': | ||
parser = OptionParser(usage='%prog [options] source destination') | ||
parser.add_option('-b', dest='files', | ||
help='colon-separated list of before-process files') | ||
parser.add_option('-e', dest='env', action='store_true', default=False, | ||
help='rewrite values with environemnt variables') | ||
parser.add_option('-d', dest='django', action='store_true', default=False, | ||
help='use Django settings as first before-process file') | ||
options, args = parser.parse_args() | ||
if len(args) != 2: | ||
parser.print_help() | ||
sys.exit(0) | ||
|
||
mtt = PyMTT(os.path.dirname(args[0])) | ||
if options.django: | ||
from django.conf import settings | ||
mtt.update_context_from_module(settings) | ||
if options.files: | ||
modules = mtt.modules_from_files(options.files.split(':')) | ||
mtt.update_context_from_modules(modules) | ||
if options.env: | ||
mtt.update_context_from_env() | ||
mtt.render_and_write(os.path.basename(args[0]), args[1]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
#!/usr/bin/env python | ||
import imp | ||
import os | ||
import sys | ||
from optparse import OptionParser | ||
|
||
from jinja2 import Environment, FileSystemLoader | ||
|
||
|
||
class PyMTT(object): | ||
ALLOWED_TYPES = (int, float, basestring, tuple, list, dict) | ||
|
||
def __init__(self, template_dir): | ||
'''Create config generator. | ||
template_dir: filesystem path to search for templates. | ||
''' | ||
self.output_dir = os.path.abspath(template_dir) | ||
self.context = {} | ||
loader = FileSystemLoader(self.output_dir) | ||
self.env = Environment(loader=loader, extensions=['jinja2.ext.with_'], | ||
trim_blocks=True) | ||
|
||
def update_context_from_module(self, module): | ||
'''Update current context from module. | ||
Updates context with attributes from the given module. | ||
Attributes which start with underscore are ignored. | ||
module: module object. | ||
''' | ||
for attr in dir(module): | ||
if attr.startswith('_'): | ||
continue | ||
val = getattr(module, attr) | ||
if any(isinstance(val, tp) for tp in self.ALLOWED_TYPES): | ||
self.context[attr] = val | ||
|
||
|
||
def update_context_from_modules(self, modules): | ||
'''Update current context from modules. | ||
Updates context with attributes from the given modules. | ||
Each module overwrites attributes of the current context. | ||
modules: iterable of module objects. | ||
''' | ||
for module in modules: | ||
self.update_context_from_module(module) | ||
|
||
def update_context_from_env(self): | ||
'''Update current context from environment.''' | ||
import os | ||
for attr, value in os.environ.iteritems(): | ||
try: | ||
value = eval(value) | ||
except: | ||
pass | ||
self.context[attr] = value | ||
|
||
def module_from_file(self, filename): | ||
'''Import module from file. | ||
filename: module path. | ||
''' | ||
return imp.load_source(filename, filename) | ||
|
||
def modules_from_files(self, filenames): | ||
'''Import modules from files. | ||
filenames: iterable of modules' paths. | ||
''' | ||
return map(self.module_from_file, filenames) | ||
|
||
def render(self, template_name): | ||
'''Render template using current context. | ||
template_name: name of the template. | ||
''' | ||
template = self.env.get_template(template_name) | ||
return template.render(self.context) | ||
|
||
def render_and_write(self, template_name, output): | ||
'''Render template using context and save it to file. | ||
template_name: name of the template. | ||
context: context dict. | ||
output: output file name or path. | ||
''' | ||
output_dir = os.path.dirname(output) | ||
if output_dir: | ||
output_dir = os.path.abspath(output_dir) | ||
else: | ||
output_dir = self.output_dir | ||
output_file = os.path.join(output_dir, os.path.basename(output)) | ||
with open(output_file, 'w') as f: | ||
f.write(self.render(template_name)) |