changeset 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 (2012-06-02)
parents 220885b2d7ee
children 71f2ac0eee95
files rgToolFactory.py rgToolFactory.xml
diffstat 2 files changed, 44 insertions(+), 56 deletions(-) [+]
line wrap: on
line diff
--- a/rgToolFactory.py	Sat Jun 02 20:02:11 2012 +1000
+++ b/rgToolFactory.py	Sat Jun 02 21:08:57 2012 +1000
@@ -43,31 +43,7 @@
     """
     return time.strftime('%d/%m/%Y %H:%M:%S', time.localtime(time.time()))
 # characters that are allowed but need to be escaped
-mapped_chars = { '>' :'__gt__',
-                 '<' :'__lt__',
-                 "'" :'__sq__',
-                 '"' :'__dq__',
-                 '{' :'__oc__',
-                 '}' :'__cc__',
-                 '@' : '__at__', 
-                 '\n' : '__cn__',
-                 '\r' : '__cr__',
-                 '\t' : '__tc__',
-                 '#' : '__pd__',
-                 '[' :'__ob__',
-                 ']' :'__cb__',
-                 '\t' : 'Xt', 
-                 'systemCallsAreNotAllowed' : 'system'
-                 }
 
-def restore_text(text):
-    """Restores sanitized text"""  
-    if not text:
-        return text
-    for key, value in mapped_chars.items():
-        text = text.replace(value, key)
-    return text
-    
 class ScriptRunner:
     """class is a wrapper for an arbitrary script
     """
@@ -75,15 +51,7 @@
     def __init__(self,opts=None):
         """
         run the script
-        cheetah/galaxy will provide an escaped string so
-        __pd__ your script goes here
-        __cr____cn__ourargs __lt__- commandArgs(TRUE)
-        __cr____cn__inf = ourargs[1]
-        __cr____cn__outf = ourargs[2]
-        __cr____cn__inp = read.table(inf,head=T,rownames=F,sep=__sq__Xt__sq__)
-        __cr____cn__ write.table(inp,outf, quote=FALSE, sep=__dq__Xt__dq__,row.names=F)
-        __cr____cn__sessionInfo()
-        __cr____cn__
+        
         """
         if opts.output_dir: # simplify for the tool tarball
             os.chdir(opts.output_dir)
@@ -92,28 +60,33 @@
         self.toolname = re.sub('[^a-zA-Z0-9_]+', '', opts.tool_name)
         self.toolid = self.toolname
         s = open(self.opts.script_path,'r').read()
-        self.script = restore_text(s)
+        self.script = s
         self.myname = sys.argv[0] # get our name because we write ourselves out as a tool later
         self.pyfile = self.myname # crude but efficient - the cruft won't hurt much
         self.xmlfile = '%s.xml' % self.toolname
         self.sfile = '%s.%s' % (self.toolname,opts.interpreter)
-        localscript = open(self.sfile,'w')
-        localscript.write(self.script)
-        localscript.close()
-        if opts.output_dir or self.opts.make_Tool: # may not want these complexities if a simple script
+        if opts.output_dir or self.opts.make_Tool: # may not want these complexities 
             self.tlog = os.path.join(opts.output_dir,"%s_runner.log" % self.toolname)
             artifactpath = os.path.join(opts.output_dir,'%s_run.script' % self.toolname) 
             artifact = open(artifactpath,'w')
             artifact.write(self.script)
             artifact.write('\n')
             artifact.close()
+            localscript = open(self.sfile,'w')
+            localscript.write(self.script)
+            localscript.close()
+            shutil.copyfile(self.myname,'%s.py' % self.toolname) # for tool and for user 
+            localpy = open('%s.py' % self.toolname,'w')
+            localpy.write(open(self.myname,'r').read())
         self.cl = []
         self.html = []
         a = self.cl.append
         a(opts.interpreter)
         a('-') # use stdin
-        a(opts.input_tab)
-        a(opts.output_tab)
+        if opts.input_tab:
+            a(opts.input_tab)
+        if opts.output_tab:
+            a(opts.output_tab)
         self.outFormats = 'tabular' # TODO make this an option at tool generation time
         self.inputFormats = 'tabular' # TODO make this an option at tool generation time
 
@@ -121,6 +94,7 @@
     def makeXML(self):
         """
         Create a Galaxy xml tool wrapper for the new script as a string to write out
+        fixme - use templating or something less fugly than this
         """    
         newXML="""<tool id="%(toolid)s" name="%(toolname)s" version="0.01">
             %(tooldesc)s
@@ -147,19 +121,17 @@
             </command>""" # may NOT be an input or htmlout
             
         xdict = {}
-        xdict['script'] = self.script # we pass this as a configfile because it's less painful that galaxy_tool_data_dir
-                                      # embed script in tool - remove dependence on something else outside in the wilds
+        xdict['script'] = self.script # configfile is least painful way to embed script to avoid external dependencies
         if self.opts.help_text:
-            h = open(self.opts.help_text,'r').read()
-            xdict['help'] = restore_text(h)
+            xdict['help'] = open(self.opts.help_text,'r').read()
         else:
             xdict['help'] = 'Please ask the tool author for help as none was supplied at tool generation'
         if self.opts.tool_desc:
             xdict['tooldesc'] = '<description>%s</description>' % self.opts.tool_desc
         else:
             xdict['tooldesc'] = ''
-        xdict['command_outputs'] = '' # will probably be some!
-        xdict['outputs'] = '' # will probably be some!
+        xdict['command_outputs'] = '' 
+        xdict['outputs'] = '' 
         if self.opts.input_tab:
             xdict['command_inputs'] = '--input_tab "$input1"'
             xdict['inputs'] = '<param name="input1"  type="data" format="%s" label="Select a suitable input file from your history"/>' % self.inputFormats
@@ -172,7 +144,7 @@
         xdict['interpreter'] = self.opts.interpreter
         xdict['scriptname'] = self.sfile
         if self.opts.make_HTML:
-            xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file"'
+            xdict['command_outputs'] += '--output_dir "$html_file.files_path" --output_html "$html_file" --make_HTML "yes"'
             xdict['outputs'] +=  '<data format="html" name="html_file" label="${job_name}.html"/>\n'
         if self.opts.output_tab:
             xdict['command_outputs'] += '--output_tab "$tab_file"'
@@ -290,14 +262,14 @@
             html.append('</table>\n')
         if len(fhtml) > 0:
            fhtml.insert(0,'<ul>')
-           fhtml.append('</ul>')
+           fhtml.append('</ul><br/>')
            html += fhtml # add all non-pdf files to the end of the display
         else:
             html.append('<h2>### Error - %s returned no files - please confirm that parameters are sane</h1>' % self.opts.interpreter)
-            html.append('<h3>%s log follows below</h3><hr/><pre>\n' % self.opts.interpreter)
+            html.append('<h3>%s log follows below</h3><hr/><pre><br/>\n' % self.opts.interpreter)
         rlog = open(self.tlog,'r').readlines()
         html += rlog
-        html.append('%s CL = %s<br/>\n' % (self.toolname,' '.join(sys.argv)))
+        html.append('<br/>%s CL = %s<br/>\n' % (self.toolname,' '.join(sys.argv)))
         html.append('</pre>\n')
         html.append(galhtmlattr % (progname,timenow()))
         html.append(galhtmlpostfix)
--- a/rgToolFactory.xml	Sat Jun 02 20:02:11 2012 +1000
+++ b/rgToolFactory.xml	Sat Jun 02 21:08:57 2012 +1000
@@ -5,10 +5,13 @@
      rgToolFactory.py --bad_user $__user_email__
   #else:
     rgToolFactory.py --script_path "$runme" --interpreter "$interpreter" 
-     --tool_name "$tool_name"  --input_tab "$input1" 
+     --tool_name "$tool_name"  
     #if $make_HTML.value=="yes" or $factory.make_Tool=="yes":
       --output_dir "$html_file.files_path" --output_html "$html_file"
     #end if
+    #if $input1.value != 'None':
+       --input_tab "$input1"
+    #end if
     #if $make_HTML.value=="yes":
     --make_HTML "yes"
     #end if
@@ -78,21 +81,24 @@
 <configfile name="runme">
 ${dynScript}
 </configfile>
+
+<configfile name="helpme">
 #if $factory.make_Tool == "yes":
-<configfile name="helpme">
 $factory.help_text
+#end if
 </configfile>
-#end if
-
 </configfiles>
 <help>
 **What it does**
 This tool enables a user to paste and submit an arbitrary R/python/perl script to run in Galaxy.
-This is (extremely) insecure.
+This is (extremely) insecure. However, once you get the script working on some test data, you can generate a complete ready to run
+Galaxy tool by setting the "Make tool" option to Yes. The resulting tarball will be ready to install
+It will run like as securely as any other Galaxy tool - unlike this one used to generate it.
 
 **Restrictions**
 This tool will ONLY work if your user id has been added to the local copy's list of permitted users.
-Ask your friendly Galaxy administrator to edit this tool's source for you if you need this.
+It should only ever be used on a private, personal Galaxy instance and you should edit this tool's source so your local login
+is authorised to use it - == it will not run otherwise ==
 
 **Note to system administrators**
 Under no circumstances should you allow any user to use this tool unless you really, really trust them to do
@@ -122,6 +128,16 @@
  outp = t(inp)
  write.table(outp,outf, quote=FALSE, sep="\t",row.names=F,col.names=F)
 
+A more complex example takes no input file but generates a random heatmap pdf - you must make sure the option to create an HTML output file is
+turned on for this to work. The heatmap will be presented as a thumbnail linked to the pdf in the resulting HTML page::
+
+ foo = data.frame(a=runif(100),b=runif(100),c=runif(100),d=runif(100),e=runif(100),f=runif(100))
+ bar = as.matrix(foo)
+ pdf( "heattest.pdf" )
+ heatmap(bar,main='Random Heatmap')
+ dev.off()
+
+
 </help>
 
 </tool>