diff --git a/pystache/commands/render.py b/pystache/commands/render.py index 1a9c309d..f0eca076 100644 --- a/pystache/commands/render.py +++ b/pystache/commands/render.py @@ -27,7 +27,8 @@ # The optparse module is deprecated in Python 2.7 in favor of argparse. # However, argparse is not available in Python 2.6 and earlier. from optparse import OptionParser -import sys +import sys, os +import csv # We use absolute imports here to allow use of this script from its # location in source control (e.g. for development purposes). @@ -40,13 +41,13 @@ USAGE = """\ -%prog [-h] template context +%prog [options] template context Render a mustache template with the given context. positional arguments: template A filename or template string. - context A filename or JSON string.""" + context A JSON string, or a JSON or CSV filename.""" def parse_args(sys_argv, usage): @@ -57,11 +58,27 @@ def parse_args(sys_argv, usage): args = sys_argv[1:] parser = OptionParser(usage=usage) + parser.add_option("-f", "--format", dest="format", + help="format of the context string of filename (choose from: 'json', 'csv'). Default is JSON, unless context is a filename with .csv extension.", + choices=("json","csv")) + parser.add_option("-m", "--multiple", dest="multiple", + help="""render the template for each context children, +writing output to KEY file (with no warning if file already exists). +If KEY is not a key of context children, then it is used as file output name, +and suffixed with a 3 digit incremental counter.""", metavar="KEY") options, args = parser.parse_args(args) - template, context = args + try: + template, context = args + except ValueError as e: + print('ERROR: %s\n' % e) + parser.print_help() + exit(1) + except UnboundLocalError as e: + print('ERROR: %s' % e) + exit(1) - return template, context + return template, context, options.format, options.multiple # TODO: verify whether the setup() method's entry_points argument @@ -70,7 +87,7 @@ def parse_args(sys_argv, usage): # http://packages.python.org/distribute/setuptools.html#automatic-script-creation # def main(sys_argv=sys.argv): - template, context = parse_args(sys_argv, USAGE) + template, context, c_format, multiple = parse_args(sys_argv, USAGE) if template.endswith('.mustache'): template = template[:-9] @@ -82,14 +99,36 @@ def main(sys_argv=sys.argv): except TemplateNotFoundError: pass - try: - context = json.load(open(context)) - except IOError: - context = json.loads(context) - - rendered = renderer.render(template, context) - print rendered - + if context.endswith(".csv") or (c_format and (c_format == "csv")): + try: + context = csv.DictReader(open(context, 'rb'))#, delimiter=',', quotechar='"') + except IOError: + print('ERROR: Could not parse context as CSV file. Check usage for input format options') + exit(-1) + else: + try: + context = json.load(open(context)) + except IOError: + context = json.loads(context) + except ValueError: #likely a not well-formed JSON string, or user forgot -f csv. + print('ERROR: Could not parse context as JSON file or text, check usage for input format options') + exit(1) + + if (multiple): + print ("multiple render on field %s" % multiple) + fileName, fileExt = os.path.splitext(multiple) + for i,c in enumerate(context): + if multiple in c: + f_name = str(c[multiple]) + else: + f_name = "%s-%03d%s" % (fileName, i, fileExt) + with open(f_name, "w") as f: # mode "wx" could be used to prevent overwriting, + pass IOError, adding "--force" option to override. + rendered = renderer.render(template, c) + f.write(rendered) + print ("%s done") % f_name + else: + rendered = renderer.render(template, context) + print rendered if __name__=='__main__': main() diff --git a/pystache/tests/examples/csv.test b/pystache/tests/examples/csv.test new file mode 120000 index 00000000..0d3c7d87 --- /dev/null +++ b/pystache/tests/examples/csv.test @@ -0,0 +1 @@ +multiple.csv \ No newline at end of file diff --git a/pystache/tests/examples/multiple.csv b/pystache/tests/examples/multiple.csv new file mode 100644 index 00000000..9cd3d004 --- /dev/null +++ b/pystache/tests/examples/multiple.csv @@ -0,0 +1,4 @@ +NO,TITLE +1,"Hello, World" +2,"Apple, Orange, and Banana" +3,"Thank you!" \ No newline at end of file diff --git a/pystache/tests/examples/multiple.json b/pystache/tests/examples/multiple.json new file mode 100644 index 00000000..e1710602 --- /dev/null +++ b/pystache/tests/examples/multiple.json @@ -0,0 +1,5 @@ +[ + { "NO": 1, "TITLE": "Hello, World" }, + { "NO": 2, "TITLE": "Apple, Orange, and Banana" }, + { "NO": 3, "TITLE": "Thank you!" } +] \ No newline at end of file diff --git a/pystache/tests/examples/multiple.mustache b/pystache/tests/examples/multiple.mustache new file mode 100644 index 00000000..fe147ff9 --- /dev/null +++ b/pystache/tests/examples/multiple.mustache @@ -0,0 +1,3 @@ +{{#.}} +