Mercurial > repos > fubar > brokenandnotdeletablebyowneroradmin
comparison rgToolFactory.py @ 9:e09c76551bed
Can run without input or output or either..
random heatmap (no inputs) example added to docs
| author | ross lazarus ross.lazarus@gmail.com |
|---|---|
| date | Sat, 02 Jun 2012 21:08:57 +1000 |
| parents | 220885b2d7ee |
| children | 71f2ac0eee95 |
comparison
equal
deleted
inserted
replaced
| 8:220885b2d7ee | 9:e09c76551bed |
|---|---|
| 41 def timenow(): | 41 def timenow(): |
| 42 """return current time as a string | 42 """return current time as a string |
| 43 """ | 43 """ |
| 44 return time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(time.time())) | 44 return time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(time.time())) |
| 45 # characters that are allowed but need to be escaped | 45 # characters that are allowed but need to be escaped |
| 46 mapped_chars = { '>' :'__gt__', | 46 |
| 47 '<' :'__lt__', | |
| 48 "'" :'__sq__', | |
| 49 '"' :'__dq__', | |
| 50 '{' :'__oc__', | |
| 51 '}' :'__cc__', | |
| 52 '@' : '__at__', | |
| 53 '\n' : '__cn__', | |
| 54 '\r' : '__cr__', | |
| 55 '\t' : '__tc__', | |
| 56 '#' : '__pd__', | |
| 57 '[' :'__ob__', | |
| 58 ']' :'__cb__', | |
| 59 '\t' : 'Xt', | |
| 60 'systemCallsAreNotAllowed' : 'system' | |
| 61 } | |
| 62 | |
| 63 def restore_text(text): | |
| 64 """Restores sanitized text""" | |
| 65 if not text: | |
| 66 return text | |
| 67 for key, value in mapped_chars.items(): | |
| 68 text = text.replace(value, key) | |
| 69 return text | |
| 70 | |
| 71 class ScriptRunner: | 47 class ScriptRunner: |
| 72 """class is a wrapper for an arbitrary script | 48 """class is a wrapper for an arbitrary script |
| 73 """ | 49 """ |
| 74 | 50 |
| 75 def __init__(self,opts=None): | 51 def __init__(self,opts=None): |
| 76 """ | 52 """ |
| 77 run the script | 53 run the script |
| 78 cheetah/galaxy will provide an escaped string so | 54 |
| 79 __pd__ your script goes here | |
| 80 __cr____cn__ourargs __lt__- commandArgs(TRUE) | |
| 81 __cr____cn__inf = ourargs[1] | |
| 82 __cr____cn__outf = ourargs[2] | |
| 83 __cr____cn__inp = read.table(inf,head=T,rownames=F,sep=__sq__Xt__sq__) | |
| 84 __cr____cn__ write.table(inp,outf, quote=FALSE, sep=__dq__Xt__dq__,row.names=F) | |
| 85 __cr____cn__sessionInfo() | |
| 86 __cr____cn__ | |
| 87 """ | 55 """ |
| 88 if opts.output_dir: # simplify for the tool tarball | 56 if opts.output_dir: # simplify for the tool tarball |
| 89 os.chdir(opts.output_dir) | 57 os.chdir(opts.output_dir) |
| 90 self.thumbformat = 'jpg' | 58 self.thumbformat = 'jpg' |
| 91 self.opts = opts | 59 self.opts = opts |
| 92 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name) | 60 self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name) |
| 93 self.toolid = self.toolname | 61 self.toolid = self.toolname |
| 94 s = open(self.opts.script_path,'r').read() | 62 s = open(self.opts.script_path,'r').read() |
| 95 self.script = restore_text(s) | 63 self.script = s |
| 96 self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later | 64 self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later |
| 97 self.pyfile = self.myname # crude but efficient - the cruft won't hurt much | 65 self.pyfile = self.myname # crude but efficient - the cruft won't hurt much |
| 98 self.xmlfile = '%s.xml' % self.toolname | 66 self.xmlfile = '%s.xml' % self.toolname |
| 99 self.sfile = '%s.%s' % (self.toolname,opts.interpreter) | 67 self.sfile = '%s.%s' % (self.toolname,opts.interpreter) |
| 100 localscript = open(self.sfile,'w') | 68 if opts.output_dir or self.opts.make_Tool: # may not want these complexities |
| 101 localscript.write(self.script) | |
| 102 localscript.close() | |
| 103 if opts.output_dir or self.opts.make_Tool: # may not want these complexities if a simple script | |
| 104 self.tlog = os.path.join(opts.output_dir,"%s_runner.log" % self.toolname) | 69 self.tlog = os.path.join(opts.output_dir,"%s_runner.log" % self.toolname) |
| 105 artifactpath = os.path.join(opts.output_dir,'%s_run.script' % self.toolname) | 70 artifactpath = os.path.join(opts.output_dir,'%s_run.script' % self.toolname) |
| 106 artifact = open(artifactpath,'w') | 71 artifact = open(artifactpath,'w') |
| 107 artifact.write(self.script) | 72 artifact.write(self.script) |
| 108 artifact.write('\n') | 73 artifact.write('\n') |
| 109 artifact.close() | 74 artifact.close() |
| 75 localscript = open(self.sfile,'w') | |
| 76 localscript.write(self.script) | |
| 77 localscript.close() | |
| 78 shutil.copyfile(self.myname,'%s.py' % self.toolname) # for tool and for user | |
| 79 localpy = open('%s.py' % self.toolname,'w') | |
| 80 localpy.write(open(self.myname,'r').read()) | |
| 110 self.cl = [] | 81 self.cl = [] |
| 111 self.html = [] | 82 self.html = [] |
| 112 a = self.cl.append | 83 a = self.cl.append |
| 113 a(opts.interpreter) | 84 a(opts.interpreter) |
| 114 a('-') # use stdin | 85 a('-') # use stdin |
| 115 a(opts.input_tab) | 86 if opts.input_tab: |
| 116 a(opts.output_tab) | 87 a(opts.input_tab) |
| 88 if opts.output_tab: | |
| 89 a(opts.output_tab) | |
| 117 self.outFormats = 'tabular' # TODO make this an option at tool generation time | 90 self.outFormats = 'tabular' # TODO make this an option at tool generation time |
| 118 self.inputFormats = 'tabular' # TODO make this an option at tool generation time | 91 self.inputFormats = 'tabular' # TODO make this an option at tool generation time |
| 119 | 92 |
| 120 | 93 |
| 121 def makeXML(self): | 94 def makeXML(self): |
| 122 """ | 95 """ |
| 123 Create a Galaxy xml tool wrapper for the new script as a string to write out | 96 Create a Galaxy xml tool wrapper for the new script as a string to write out |
| 97 fixme - use templating or something less fugly than this | |
| 124 """ | 98 """ |
| 125 newXML="""<tool id="%(toolid)s" name="%(toolname)s" version="0.01"> | 99 newXML="""<tool id="%(toolid)s" name="%(toolname)s" version="0.01"> |
| 126 %(tooldesc)s | 100 %(tooldesc)s |
| 127 %(command)s | 101 %(command)s |
| 128 <inputs> | 102 <inputs> |
| 145 %(toolname)s.py --script_path "$runMe" --interpreter "%(interpreter)s" | 119 %(toolname)s.py --script_path "$runMe" --interpreter "%(interpreter)s" |
| 146 --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s | 120 --tool_name "%(toolname)s" %(command_inputs)s %(command_outputs)s |
| 147 </command>""" # may NOT be an input or htmlout | 121 </command>""" # may NOT be an input or htmlout |
| 148 | 122 |
| 149 xdict = {} | 123 xdict = {} |
| 150 xdict['script'] = self.script # we pass this as a configfile because it's less painful that galaxy_tool_data_dir | 124 xdict['script'] = self.script # configfile is least painful way to embed script to avoid external dependencies |
| 151 # embed script in tool - remove dependence on something else outside in the wilds | |
| 152 if self.opts.help_text: | 125 if self.opts.help_text: |
| 153 h = open(self.opts.help_text,'r').read() | 126 xdict['help'] = open(self.opts.help_text,'r').read() |
| 154 xdict['help'] = restore_text(h) | |
| 155 else: | 127 else: |
| 156 xdict['help'] = 'Please ask the tool author for help as none was supplied at tool generation' | 128 xdict['help'] = 'Please ask the tool author for help as none was supplied at tool generation' |
| 157 if self.opts.tool_desc: | 129 if self.opts.tool_desc: |
| 158 xdict['tooldesc'] = '<description>%s</description>' % self.opts.tool_desc | 130 xdict['tooldesc'] = '<description>%s</description>' % self.opts.tool_desc |
| 159 else: | 131 else: |
| 160 xdict['tooldesc'] = '' | 132 xdict['tooldesc'] = '' |
| 161 xdict['command_outputs'] = '' # will probably be some! | 133 xdict['command_outputs'] = '' |
| 162 xdict['outputs'] = '' # will probably be some! | 134 xdict['outputs'] = '' |
| 163 if self.opts.input_tab: | 135 if self.opts.input_tab: |
| 164 xdict['command_inputs'] = '--input_tab "$input1"' | 136 xdict['command_inputs'] = '--input_tab "$input1"' |
| 165 xdict['inputs'] = '<param name="input1" type="data" format="%s" label="Select a suitable input file from your history"/>' % self.inputFormats | 137 xdict['inputs'] = '<param name="input1" type="data" format="%s" label="Select a suitable input file from your history"/>' % self.inputFormats |
| 166 else: | 138 else: |
| 167 xdict['command_inputs'] = '' # assume no input - eg a random data generator | 139 xdict['command_inputs'] = '' # assume no input - eg a random data generator |
| 170 xdict['toolname'] = self.toolname | 142 xdict['toolname'] = self.toolname |
| 171 xdict['toolid'] = self.toolid | 143 xdict['toolid'] = self.toolid |
| 172 xdict['interpreter'] = self.opts.interpreter | 144 xdict['interpreter'] = self.opts.interpreter |
| 173 xdict['scriptname'] = self.sfile | 145 xdict['scriptname'] = self.sfile |
| 174 if self.opts.make_HTML: | 146 if self.opts.make_HTML: |
| 175 xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file"' | 147 xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file" --make_HTML "yes"' |
| 176 xdict['outputs'] += '<data format="html" name="html_file" label="${job_name}.html"/>\n' | 148 xdict['outputs'] += '<data format="html" name="html_file" label="${job_name}.html"/>\n' |
| 177 if self.opts.output_tab: | 149 if self.opts.output_tab: |
| 178 xdict['command_outputs'] += '--output_tab "$tab_file"' | 150 xdict['command_outputs'] += '--output_tab "$tab_file"' |
| 179 xdict['outputs'] += '<data format="%s" name="tab_file" label="${job_name}"/>\n' % self.outFormats | 151 xdict['outputs'] += '<data format="%s" name="tab_file" label="${job_name}"/>\n' % self.outFormats |
| 180 xdict['command'] = newCommand % xdict | 152 xdict['command'] = newCommand % xdict |
| 288 else: | 260 else: |
| 289 fhtml.append('<li><a href="%s">%s %s</a></li>' % (fname,fname,sfsize)) | 261 fhtml.append('<li><a href="%s">%s %s</a></li>' % (fname,fname,sfsize)) |
| 290 html.append('</table>\n') | 262 html.append('</table>\n') |
| 291 if len(fhtml) > 0: | 263 if len(fhtml) > 0: |
| 292 fhtml.insert(0,'<ul>') | 264 fhtml.insert(0,'<ul>') |
| 293 fhtml.append('</ul>') | 265 fhtml.append('</ul><br/>') |
| 294 html += fhtml # add all non-pdf files to the end of the display | 266 html += fhtml # add all non-pdf files to the end of the display |
| 295 else: | 267 else: |
| 296 html.append('<h2>### Error - %s returned no files - please confirm that parameters are sane</h1>' % self.opts.interpreter) | 268 html.append('<h2>### Error - %s returned no files - please confirm that parameters are sane</h1>' % self.opts.interpreter) |
| 297 html.append('<h3>%s log follows below</h3><hr/><pre>\n' % self.opts.interpreter) | 269 html.append('<h3>%s log follows below</h3><hr/><pre><br/>\n' % self.opts.interpreter) |
| 298 rlog = open(self.tlog,'r').readlines() | 270 rlog = open(self.tlog,'r').readlines() |
| 299 html += rlog | 271 html += rlog |
| 300 html.append('%s CL = %s<br/>\n' % (self.toolname,' '.join(sys.argv))) | 272 html.append('<br/>%s CL = %s<br/>\n' % (self.toolname,' '.join(sys.argv))) |
| 301 html.append('</pre>\n') | 273 html.append('</pre>\n') |
| 302 html.append(galhtmlattr % (progname,timenow())) | 274 html.append(galhtmlattr % (progname,timenow())) |
| 303 html.append(galhtmlpostfix) | 275 html.append(galhtmlpostfix) |
| 304 htmlf = file(self.opts.output_html,'w') | 276 htmlf = file(self.opts.output_html,'w') |
| 305 htmlf.write('\n'.join(html)) | 277 htmlf.write('\n'.join(html)) |
