changeset 18:4434ffab721a

add a parameter for the template
author Jan Kanis <jan.code@jankanis.nl>
date Tue, 13 May 2014 15:26:20 +0200
parents 8e61627a87f1
children 67ddcb807b7d
files blast_html.py
diffstat 1 files changed, 28 insertions(+), 19 deletions(-) [+]
line wrap: on
line diff
--- a/blast_html.py	Tue May 13 12:54:03 2014 +0200
+++ b/blast_html.py	Tue May 13 15:26:20 2014 +0200
@@ -6,6 +6,7 @@
 import sys
 import math
 import warnings
+from os import path
 from itertools import repeat
 import argparse
 from lxml import objectify
@@ -115,7 +116,7 @@
 )
 
 # Escape every ASCII character with a value less than 32. This is
-# needed a.o. to prevent parsers from jumping out of javascript
+# needed a.o. to prevent html parsers from jumping out of javascript
 # parsing mode.
 _js_escapes = (_base_js_escapes +
                tuple(('%c' % z, '\\u%04X' % z) for z in range(32)))
@@ -141,21 +142,18 @@
 
     max_scale_labels = 10
 
-    templatename = 'blast_html.html.jinja'
-
-    def __init__(self, input):
+    def __init__(self, input, templatedir, templatename):
         self.input = input
+        self.templatename = templatename
 
         self.blast = objectify.parse(self.input).getroot()
-        self.loader = jinja2.FileSystemLoader(searchpath='.')
+        self.loader = jinja2.FileSystemLoader(searchpath=templatedir)
         self.environment = jinja2.Environment(loader=self.loader,
                                               lstrip_blocks=True, trim_blocks=True, autoescape=True)
 
+        self.environment.filters.update(_filters)
         self.environment.filters['color'] = lambda length: match_colors[color_idx(length)]
 
-        for name, filter in _filters.items():
-            self.environment.filters[name] = filter
-
         self.query_length = int(self.blast["BlastOutput_query-len"])
         self.hits = self.blast.BlastOutput_iterations.Iteration.Iteration_hits.Hit
         # sort hits by longest hotspot first
@@ -177,15 +175,15 @@
             warnings.warn("Multiple 'Iteration' elements found, showing only the first")
 
         output.write(template.render(blast=self.blast,
-                                          length=self.query_length,
-                                          hits=self.blast.BlastOutput_iterations.Iteration.Iteration_hits.Hit,
-                                          colors=self.colors,
-                                          match_colors=self.match_colors(),
-                                          queryscale=self.queryscale(),
-                                          hit_info=self.hit_info(),
-                                          genelink=genelink,
-                                          params=params))
-            
+                                     length=self.query_length,
+                                     hits=self.blast.BlastOutput_iterations.Iteration.Iteration_hits.Hit,
+                                     colors=self.colors,
+                                     match_colors=self.match_colors(),
+                                     queryscale=self.queryscale(),
+                                     hit_info=self.hit_info(),
+                                     genelink=genelink,
+                                     params=params))
+        
 
     def match_colors(self):
         """
@@ -253,7 +251,6 @@
                        ident = "{:.0%}".format(float(min(hsp.Hsp_identity / hsplen(hsp) for hsp in hsps))),
                        accession = hit.Hit_accession)
 
-
 def main():
 
     parser = argparse.ArgumentParser(description="Convert a BLAST XML result into a nicely readable html page",
@@ -265,6 +262,13 @@
                              help='The input Blast XML file')
     parser.add_argument('-o', '--output', type=argparse.FileType(mode='w'), default=sys.stdout,
                         help='The output html file')
+    # We just want the file name here, so jinja can open the file
+    # itself. But it is easier to just use a FileType so argparse can
+    # handle the errors. This introduces a small race condition when
+    # jinja later tries to re-open the template file, but we don't
+    # care too much.
+    parser.add_argument('--template', type=argparse.FileType(mode='r'), default='blast_html.html.jinja',
+                        help='The template file to use. Defaults to blast_html.html.jinja')
 
     args = parser.parse_args()
     if args.input == None:
@@ -272,7 +276,12 @@
     if args.input == None:
         parser.error('no input specified')
 
-    b = BlastVisualize(args.input)
+    templatedir, templatename = path.split(args.template.name)
+    args.template.close()
+    if not templatedir:
+        templatedir = '.'
+
+    b = BlastVisualize(args.input, templatedir, templatename)
     b.render(args.output)