workflow-to-galaxy 0.2.9 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/doc/rdoc/created.rid CHANGED
@@ -1,8 +1,7 @@
1
- Tue, 26 Jul 2011 16:38:29 +0200
2
- lib/generator.rb Tue, 26 Jul 2011 16:35:55 +0200
3
- lib/workflow-to-galaxy.rb Tue, 26 Jul 2011 16:35:55 +0200
1
+ Thu, 13 Oct 2011 12:56:15 +0200
2
+ lib/workflow-to-galaxy.rb Thu, 13 Oct 2011 12:51:40 +0200
3
+ lib/workflow-to-galaxy/constants.rb Mon, 10 Oct 2011 14:10:32 +0200
4
+ lib/workflow-to-galaxy/galaxy.rb Thu, 13 Oct 2011 12:47:28 +0200
4
5
  LICENSE Tue, 26 Jul 2011 16:35:55 +0200
5
- lib/workflow_to_galaxy.rb Tue, 26 Jul 2011 16:35:55 +0200
6
- README Tue, 26 Jul 2011 16:35:55 +0200
7
- CHANGES Tue, 26 Jul 2011 16:35:55 +0200
8
- lib/workflow-to-galaxy/generator.rb Tue, 26 Jul 2011 16:35:55 +0200
6
+ README Tue, 04 Oct 2011 17:25:08 +0200
7
+ CHANGES Thu, 13 Oct 2011 12:55:19 +0200
data/doc/rdoc/index.html CHANGED
@@ -29,7 +29,7 @@
29
29
  <p>Konstantinos Karasavvas</p>
30
30
  </td></tr><tr><td class="rdoc-term"><p>Gem Version</p></td>
31
31
  <td>
32
- <p>0.2.9</p>
32
+ <p>0.3.0</p>
33
33
  </td></tr><tr><td class="rdoc-term"><p>Contact</p></td>
34
34
  <td>
35
35
  <p><a href="mailto:kostas.karasavvas@nbic.nl">kostas.karasavvas@nbic.nl</a></p>
@@ -120,20 +120,20 @@ href="https://trac.nbic.nl/elabfactory/wiki/eGalaxy">trac.nbic.nl/elabfactory/wi
120
120
  <h2 id="classes">Classes/Modules</h2>
121
121
  <ul>
122
122
 
123
- <li class="module"><a href="Generator.html">Generator</a></li>
123
+ <li class="module"><a href="WorkflowToGalaxy.html">WorkflowToGalaxy</a></li>
124
124
 
125
- <li class="class"><a href="Object.html">Object</a></li>
125
+ <li class="class"><a href="WorkflowToGalaxy/GalaxyTool.html">WorkflowToGalaxy::GalaxyTool</a></li>
126
126
 
127
- <li class="module"><a href="WorkflowToGalaxy.html">WorkflowToGalaxy</a></li>
127
+ <li class="module"><a href="WorkflowToGalaxy/Workflows.html">WorkflowToGalaxy::Workflows</a></li>
128
128
 
129
129
  </ul>
130
130
 
131
131
  <h2 id="methods">Methods</h2>
132
132
  <ul>
133
133
 
134
- <li><a href="Generator.html#method-i-generate_script">#generate_script &mdash; Generator</a></li>
134
+ <li><a href="WorkflowToGalaxy/GalaxyTool.html#method-c-new">::new &mdash; WorkflowToGalaxy::GalaxyTool</a></li>
135
135
 
136
- <li><a href="Generator.html#method-i-generate_xml">#generate_xml &mdash; Generator</a></li>
136
+ <li><a href="WorkflowToGalaxy/GalaxyTool.html#method-i-generate">#generate &mdash; WorkflowToGalaxy::GalaxyTool</a></li>
137
137
 
138
138
  </ul>
139
139
 
@@ -0,0 +1,52 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
3
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
4
+
5
+ <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
6
+ <head>
7
+ <meta content="text/html; charset=UTF-8" http-equiv="Content-Type" />
8
+
9
+ <title>File: constants.rb [workflow-to-galaxy Docs]</title>
10
+
11
+ <link type="text/css" media="screen" href="../../rdoc.css" rel="stylesheet" />
12
+
13
+ <script src="../../js/jquery.js" type="text/javascript"
14
+ charset="utf-8"></script>
15
+ <script src="../../js/thickbox-compressed.js" type="text/javascript"
16
+ charset="utf-8"></script>
17
+ <script src="../../js/quicksearch.js" type="text/javascript"
18
+ charset="utf-8"></script>
19
+ <script src="../../js/darkfish.js" type="text/javascript"
20
+ charset="utf-8"></script>
21
+ </head>
22
+
23
+ <body class="file file-popup">
24
+ <div id="metadata">
25
+ <dl>
26
+ <dt class="modified-date">Last Modified</dt>
27
+ <dd class="modified-date">Mon Oct 10 14:10:32 +0200 2011</dd>
28
+
29
+
30
+ <dt class="requires">Requires</dt>
31
+ <dd class="requires">
32
+ <ul>
33
+
34
+ </ul>
35
+ </dd>
36
+
37
+
38
+
39
+ </dl>
40
+ </div>
41
+
42
+ <div id="documentation">
43
+
44
+ <div class="description">
45
+ <h2>Description</h2>
46
+
47
+ </div>
48
+
49
+ </div>
50
+ </body>
51
+ </html>
52
+
@@ -24,13 +24,19 @@
24
24
  <div id="metadata">
25
25
  <dl>
26
26
  <dt class="modified-date">Last Modified</dt>
27
- <dd class="modified-date">Tue Jul 26 16:35:55 +0200 2011</dd>
27
+ <dd class="modified-date">Thu Oct 13 12:25:01 +0200 2011</dd>
28
28
 
29
29
 
30
30
  <dt class="requires">Requires</dt>
31
31
  <dd class="requires">
32
32
  <ul>
33
33
 
34
+ <li>myexperiment-rest</li>
35
+
36
+ <li>t2flow/model.rb</li>
37
+
38
+ <li>t2flow/parser.rb</li>
39
+
34
40
  </ul>
35
41
  </dd>
36
42
 
@@ -44,9 +50,6 @@
44
50
  <div class="description">
45
51
  <h2>Description</h2>
46
52
 
47
- <p>The <a href="../../Generator.html">Generator</a> module contains two public
48
- methods that generate a Galaxy’s tool XML and script files</p>
49
-
50
53
  </div>
51
54
 
52
55
  </div>
@@ -24,14 +24,16 @@
24
24
  <div id="metadata">
25
25
  <dl>
26
26
  <dt class="modified-date">Last Modified</dt>
27
- <dd class="modified-date">Tue Jul 26 16:35:55 +0200 2011</dd>
27
+ <dd class="modified-date">Thu Oct 13 12:51:40 +0200 2011</dd>
28
28
 
29
29
 
30
30
  <dt class="requires">Requires</dt>
31
31
  <dd class="requires">
32
32
  <ul>
33
33
 
34
- <li>workflow-to-galaxy/generator</li>
34
+ <li>workflow-to-galaxy/galaxy</li>
35
+
36
+ <li>workflow-to-galaxy/constants</li>
35
37
 
36
38
  </ul>
37
39
  </dd>
@@ -1,5 +1,7 @@
1
- require 'workflow-to-galaxy/generator'
1
+ require 'workflow-to-galaxy/galaxy'
2
+ require 'workflow-to-galaxy/constants'
2
3
 
3
- module WorkflowToGalaxy
4
+
5
+ module WorkflowToGalaxy # TODO rename to WorkflowWrappers?
4
6
 
5
7
  end
@@ -0,0 +1,8 @@
1
+ module WorkflowToGalaxy
2
+
3
+ module Workflows
4
+ MYEXPERIMENT_TAVERNA2 = "myexperiment_taverna2"
5
+ T2FLOW = "t2flow"
6
+ end
7
+
8
+ end
@@ -0,0 +1,628 @@
1
+ require 'myexperiment-rest'
2
+ require 't2flow/model.rb'
3
+ require 't2flow/parser.rb'
4
+
5
+
6
+ module WorkflowToGalaxy
7
+ include MyExperimentREST
8
+
9
+
10
+ #
11
+ # The _GalaxyTool_ class contains a +generate+ public method that generates the
12
+ # required files (XML and script) for a Galaxy tool.
13
+ #
14
+ class GalaxyTool
15
+
16
+ # +config+ contains data needed in relation to what the tool will do and
17
+ # +wkf_object+ contains the workflow object that will be used to generate
18
+ # the galaxy tool
19
+ attr_accessor :wkf_object, :config
20
+
21
+
22
+ # Instantiates a galaxy tool generator.
23
+ # +config+ is a hash:
24
+ #
25
+ # :wkf_source (initial workflow input, see Workflows module)
26
+ # :params (a hash with the following parameters -- MYEXPERIMENT_TAVERNA2)
27
+ # :t2_server (the t2 server)
28
+ # :url (the myexperiment workflow URL)
29
+ # :xml_out (the file handle for the generated xml -- optional)
30
+ # :rb_out (the file handle for the generated rb -- optional)
31
+ #
32
+ # :params (a hash with the following parameters -- T2FLOW)
33
+ # :t2flow (the file name and path)
34
+ # :xml_out (the file handle for the generated xml -- optional)
35
+ # :rb_out (the file handle for the generated rb -- optional)
36
+
37
+ #-
38
+ # TODO: does initialize appear in rdoc? -- these will go to README as well...
39
+ def initialize(config)
40
+ @config = config
41
+ end
42
+
43
+
44
+
45
+ # private methods
46
+ private
47
+
48
+ # Used to create indentation when generating code
49
+ def indent(n)
50
+ ind = ""
51
+ n.times { ind += " " }
52
+ ind
53
+ end
54
+
55
+ # Galaxy's XML tool tag
56
+ def tool_begin_tag(out, name)
57
+ out.write("<tool id=\"#{name}_id\" name=\"#{name}\">\n")
58
+ end
59
+
60
+ # Galaxy's XML command tag
61
+ def command_tag(out, t2_workflow, script)
62
+ out.write indent(1) + "<command interpreter=\"ruby\">\n"
63
+ out.write indent(2) + script + "\n"
64
+
65
+ # inputs
66
+ t2_workflow.inputs.each do |i|
67
+ out.write indent(2) + "#if $#{i.name}_source.history_or_textfield == \"textfield\":\n"
68
+ out.write indent(3) + "false \"$#{i.name}_source.textfield_#{i.name}\"\n"
69
+ out.write indent(2) + "#else:\n"
70
+ out.write indent(3) + "true \"$#{i.name}_source.history_#{i.name}\"\n"
71
+ out.write indent(2) + "#end if\n"
72
+ end
73
+
74
+ # results as zip input
75
+ out.write indent(2) + "$results_as_zip\n"
76
+
77
+ # outputs
78
+ out.write indent(2)
79
+ t2_workflow.outputs.each do |o|
80
+ out.write "$#{o.name} "
81
+ end
82
+
83
+ # result zip output
84
+ out.write "$result_zip\n"
85
+
86
+ out.write indent(1) + "</command>\n"
87
+ end
88
+
89
+
90
+ # Galaxy's XML inputs tag
91
+ def inputs_tag(out, inputs)
92
+ out.write indent(1) + "<inputs>\n"
93
+ if inputs.size >= 1
94
+ inputs.each do |i|
95
+ out.write indent(2) + "<conditional name=\"#{i.name}_source\">\n"
96
+ out.write indent(3) + "<param name=\"history_or_textfield\" type=\"select\" label=\"Select source for #{i.name}\">\n"
97
+ out.write indent(4) + "<option value=\"history\">From history</option>\n"
98
+ out.write indent(4) + "<option value=\"textfield\" selected=\"true\">Type manually</option>\n"
99
+ out.write indent(3) + "</param>\n"
100
+ out.write indent(3) + "<when value=\"history\">\n"
101
+ out.write indent(4) + "<param name=\"history_#{i.name}\" type=\"data\" label=\"Select #{i.name}\"/>\n"
102
+ out.write indent(3) + "</when>\n"
103
+ out.write indent(3) + "<when value=\"textfield\">\n"
104
+ out.write indent(4) + "<param name=\"textfield_#{i.name}\" type=\"text\" area=\"True\" size=\"2x50\" "
105
+ if i.examples.size >= 1
106
+ # escape double quotes characters for galaxy's xml file
107
+ ex = i.examples[0].to_s.gsub('"', '&quot;')
108
+ # convert newlines to HTML newlines to display in textareas inputs
109
+ ex = ex.gsub(/[\n]/, '&#xA;')
110
+ out.write "value=\"#{ex}\" "
111
+ end
112
+ out.write "label=\"Enter #{i.name}\"/>\n"
113
+ out.write indent(3) + "</when>\n"
114
+ out.write indent(2) + "</conditional>\n"
115
+ end
116
+ else
117
+ out.write indent(2) + "<param name=\"input\" type=\"select\" display=\"radio\" size=\"250\" label=\"This workflow has no inputs\" />\n"
118
+ end
119
+
120
+ # result as zip input
121
+ out.write indent(2) + "<param name=\"results_as_zip\" type=\"select\" label=\"Would you also like the raw results as a zip file\">\n"
122
+ out.write indent(3) + "<option value=\"yes\">Yes</option>\n"
123
+ out.write indent(3) + "<option value=\"no\" selected=\"true\">No</option>\n"
124
+ out.write indent(2) + "</param>\n"
125
+
126
+ out.write indent(1) + "</inputs>\n"
127
+ end
128
+
129
+ # Galaxy's XML outputs tag
130
+ def outputs_tag(out, outputs)
131
+ out.write indent(1) + "<outputs>\n"
132
+ outputs.each do |o|
133
+ out.write indent(2) + "<data format=\"tabular\" name=\"#{o.name}\" label=\"#{o.name}\"/>\n"
134
+ end
135
+
136
+ # result zip output
137
+ out.write indent(2) + "<data format=\"zip\" name=\"result_zip\" label=\"Compressed Results (zip)\">\n"
138
+ out.write indent(3) + "<filter>results_as_zip == \"yes\"</filter>\n"
139
+ out.write indent(2) + "</data>\n"
140
+
141
+ out.write indent(1) + "</outputs>\n"
142
+ end
143
+
144
+ # Galaxy's XML help tag
145
+ def help_tag(out, t2_workflow)
146
+ out.write indent(1) + "<help>\n"
147
+
148
+ if t2_workflow.description
149
+ out.write "**What it does**\n\n"
150
+
151
+ description = t2_workflow.description + "\n\n"
152
+
153
+ # Sometimes the workflow description contains HTML tags that are not allowed
154
+ # in Galaxy's xml interface specification and thus are removed! Same for
155
+ # HTML entities!
156
+ # TODO go through tags and find Galaxy's equivalent to include
157
+ description.gsub!(/<.*?>|&.*?;/, '')
158
+
159
+ # To remove ^M (cntl-v + cntl-m) characters that DOS files might have
160
+ description.gsub!(/\r/, '')
161
+
162
+ # TODO that works as a literal too but font changes to courier!
163
+ #out.write "::\n\n" # Start Galaxy's literal block to ignore indendation
164
+
165
+ # remove indendation from all description lines since Galaxy is confused by it
166
+ description.split(/[\n]/).each { |l| out.write "#{l.gsub(/^\s+/, '')}\n" }
167
+
168
+ # endline makes the following be parsed as a Galaxy GUI construct
169
+ out.write "\n"
170
+ end
171
+
172
+ # if at least one input add it to tool's UI help description
173
+ if t2_workflow.inputs.size >= 1
174
+ out.write "-----\n\n"
175
+ out.write "**Inputs**\n\n"
176
+ t2_workflow.inputs.each do |i|
177
+ out.write "- **#{i.name}** "
178
+ if i.descriptions.size >= 1
179
+ i.descriptions.each do |desc|
180
+ out.write desc.to_s + " "
181
+ end
182
+ end
183
+ if i.examples.size >= 1
184
+ out.write "Examples include:\n\n"
185
+ i.examples.each do |ex|
186
+ # some examples have a newline between them that breaks Galaxy's GUI
187
+ # so we substitute it with ' '
188
+ #out.write " - " + ex.to_s.gsub(/[\n]/, ' ') + "\n"
189
+
190
+ # We could substitute them with with &#xA; that works for HTML (e.g. wkf 1180)
191
+ # But if an example input is truly multiline then input descr. will
192
+ # display them all as separate inputs...
193
+ out.write " - " + ex.to_s.gsub(/[\n]/, '&#xA; - ') + "\n"
194
+
195
+ # display example inputs as verbatim/literal so it is not our responsibility!!
196
+ # add indendation after each newline to specify the literal block
197
+ # TODO this looks ugly if we don't remove all the bullet points!
198
+ #out.write "::\n\n " + ex.to_s.gsub(/\n/, '&#xA; ') + "\n"
199
+ end
200
+ end
201
+ out.write "\n"
202
+ end
203
+ out.write "\n"
204
+ end
205
+
206
+ # if at least one output add it to tool's UI help description
207
+ if t2_workflow.outputs.size >= 1
208
+ out.write "-----\n\n"
209
+ out.write "**Outputs**\n\n"
210
+ t2_workflow.outputs.each do |o|
211
+ out.write "- **#{o.name}** "
212
+ if o.descriptions.size >= 1
213
+ o.descriptions.each do |desc|
214
+ out.write desc.to_s + " "
215
+ end
216
+ end
217
+ if o.examples.size >= 1
218
+ out.write "Examples include:\n\n"
219
+ o.examples.each do |ex|
220
+ out.write " - " + ex.to_s + "\n"
221
+ end
222
+ end
223
+ out.write "\n"
224
+ end
225
+ out.write "\n"
226
+ end
227
+
228
+ out.write "-----\n\n"
229
+ out.write ".. class:: warningmark\n\n"
230
+ out.write "**Please note that some workflows are not up-to-date or have dependencies** " <<
231
+ "that cannot be met by the specific Taverna server that you specified during " <<
232
+ "generation of this tool. You can make sure that the workflow is valid " <<
233
+ "by running it in the Taverna Workbench first to confirm that it works " <<
234
+ "before running it via Galaxy.\n\n"
235
+
236
+ if @config[:wkf_source] == Workflows::MYEXPERIMENT_TAVERNA2
237
+ out.write "-----\n\n"
238
+ out.write ".. class:: warningmark\n\n"
239
+ out.write "**Please note that there might be some repetitions in the workflow description** " <<
240
+ "in some of the generated workflows. This is due to a backwards compatibility " <<
241
+ "issue on the myExperiment repository which keeps the old descriptions to make " <<
242
+ "sure that no information is lost.\n\n"
243
+
244
+ out.write "-----\n\n"
245
+ out.write ".. class:: infomark\n\n"
246
+ out.write "**For more information on that workflow please visit** #{t2_workflow.content_uri.gsub(/(.*workflows\/\d+)[\/.].*/, '\1')}.\n\n"
247
+ end
248
+
249
+ out.write indent(1) + "</help>\n"
250
+ end
251
+
252
+ # Galaxy's XML tool tag close
253
+ def tool_end_tag(out)
254
+ out.write("</tool>\n")
255
+ end
256
+
257
+
258
+
259
+ # Galaxy's script preample
260
+ def script_preample(out)
261
+ out.write("#!/usr/bin/env ruby\n\n")
262
+
263
+ out.write("# This script can be tested without Galaxy. You can run from the shell as follows:\n#\n")
264
+ out.write("# $ script_name.rb <input1> true|false <input2> true|false yes|no <output1> <output2>\n#\n")
265
+ out.write("# After each input value a boolean specifies if the value is literal (false) or if\n")
266
+ out.write("# it specifies a file name to read as input.\n#\n")
267
+ out.write("# After all workflow inputs a yes or no input specifies if we also want our results zipped.\n#\n")
268
+ out.write("# Finally, all the output files follow. Note that if you selected to also get a zip\n")
269
+ out.write("# then you need to specify an additional output in the end after the normal workflow\n")
270
+ out.write("# outputs.\n\n")
271
+
272
+ out.write("require 'rubygems'\n")
273
+ out.write("require 't2-server'\n")
274
+ out.write("require 'open-uri'\n")
275
+ out.write("require 'zip/zipfilesystem'\n\n")
276
+ end
277
+
278
+
279
+ # Galaxy's script utility methods
280
+ # TODO: use ruby's flatten instead of our own !!!
281
+ def script_util_methods(out)
282
+
283
+ out.write <<'UTIL_METHODS'
284
+
285
+ # sends the zip file to specified output
286
+ def output_zip_file(uuid, zip_out)
287
+ File.open("/tmp/#{uuid}.zip") do |zip|
288
+ while data = zip.read(4096)
289
+ zip_out.write data
290
+ end
291
+ end
292
+ File.delete("/tmp/#{uuid}.zip")
293
+ end
294
+
295
+
296
+ #
297
+ # replicates the directory result structure as constructed by the
298
+ # taverna server and recreates it in a zip File
299
+ #
300
+ def add_to_zip_file(output_dir, data_lists, zip_out)
301
+ zip_out.dir.mkdir("#{output_dir}")
302
+ data_lists.each_with_index do |item, index|
303
+ if item.instance_of? Array
304
+ add_to_zip_file("#{output_dir}/#{index+1}", item, zip_out)
305
+ else
306
+ zip_out.file.open("#{output_dir}/#{index+1}", "w") { |f| f.puts item }
307
+ end
308
+ end
309
+ end
310
+
311
+
312
+ # method that flattens the list of list of list ... result of get_output
313
+ def print_flattened_result(out, data_lists)
314
+ data_lists.each do |l|
315
+ if l.instance_of? Array
316
+ print_flattened_result(out, l)
317
+ else
318
+ out.puts l
319
+ end
320
+ end
321
+ end
322
+
323
+
324
+ #
325
+ # Method that acquires all the results of the specified output directory.
326
+ # If valid zip File is passed it also accumulates results as a zip file.
327
+ #
328
+ def get_outputs(run, refs, outfile, dir, zip_out=nil)
329
+ data_lists = run.get_output(dir, refs)
330
+ print_flattened_result(outfile, data_lists)
331
+ if zip_out
332
+ add_to_zip_file(dir, data_lists, zip_out)
333
+ end
334
+ end
335
+
336
+
337
+ #
338
+ # Sanitize all special characters in UI inputs that Galaxy substitutes for
339
+ # security reasons. This methods turns them back to their original values before
340
+ # using them (i.e. sending them to the taverna server
341
+ # NB: note that double quote is sanitized to "'" that is because the double code
342
+ # confuses the Taverna server ruby library. Apparently, this is not trivial
343
+ # to fix.
344
+ #
345
+ def sanitize(string)
346
+ string.gsub(/(__sq__|__dq__|__at__|__cr__|__cn__|__tc__|__gt__|__lt__|__ob__|__cb__|__oc__|__cc__)/) do
347
+ if $1 == '__sq__'
348
+ "'"
349
+ elsif $1 == '__dq__'
350
+ "'"
351
+ elsif $1 == '__cr__'
352
+ "\r"
353
+ elsif $1 == '__cn__'
354
+ "\n"
355
+ elsif $1 == '__tc__'
356
+ "\t"
357
+ elsif $1 == '__gt__'
358
+ '>'
359
+ elsif $1 == '__lt__'
360
+ '<'
361
+ elsif $1 == '__ob__'
362
+ '['
363
+ elsif $1 == '__cb__'
364
+ ']'
365
+ elsif $1 == '__oc__'
366
+ '{'
367
+ elsif $1 == '__cc__'
368
+ '}'
369
+ else
370
+ '@'
371
+ end
372
+ end
373
+ end
374
+
375
+ #
376
+ # Deletes last new line of file if it exists! It is needed for t2 workflows that
377
+ # do not sanitize properly, i.e. via a user-provided beanshell script
378
+ #
379
+ def chomp_last_newline(file)
380
+
381
+ if File.file?(file) and File.size(file) > 1
382
+ f = open(file, "rb+")
383
+ f.seek(-1, File::SEEK_END)
384
+ f.truncate(File.size(file) - 1) if f.read(1) == "\n"
385
+ f.close
386
+ end
387
+
388
+ end
389
+
390
+
391
+ UTIL_METHODS
392
+
393
+ end
394
+
395
+ # Galaxy's script taverna 2 run
396
+ def script_create_t2_run(out, wkf, t2_uri)
397
+ if @config[:wkf_source] == Workflows::MYEXPERIMENT_TAVERNA2
398
+ out.write "# use the uri reference to download the workflow locally\n"
399
+ out.write "wkf_file = URI.parse('#{wkf.content_uri}')\n"
400
+ out.write "in_wkf = open(wkf_file)\n"
401
+ else # Workflows::T2FLOW
402
+ out.write "# uri contains local t2flow file\n"
403
+ out.write "in_wkf = open('#{wkf.content_uri}')\n"
404
+ end
405
+
406
+ out.write <<CREATE_T2_RUN
407
+
408
+ wkf = in_wkf.read()
409
+
410
+ # create run
411
+ begin
412
+ run = T2Server::Run.create('#{t2_uri}', wkf)
413
+ rescue T2Server::T2ServerError => e
414
+ exit 1
415
+ end
416
+
417
+ CREATE_T2_RUN
418
+
419
+ end
420
+
421
+
422
+ # Galaxy's script input handling
423
+ def script_init_inputs(out, t2_workflow)
424
+ out.write "#\n"
425
+ out.write "# Get input arguments -- for each input a boolean specifies if it's from history\n"
426
+ out.write "# thus, for each t2_workflow input we have two arguments in the script!\n"
427
+ out.write "#\n"
428
+ t2_workflow.inputs.each_with_index do |input, i|
429
+ i_name = input.name.to_s
430
+ out.write "#{i_name}_from_history = ARGV[#{i*2}].chomp\n"
431
+ out.write "#{i_name}_tmp = ARGV[#{i*2+1}].chomp\n"
432
+ out.write "if #{i_name}_from_history == \"true\"\n"
433
+ out.write " chomp_last_newline(#{i_name}_tmp)\n"
434
+ out.write " run.upload_input_file('#{i_name}', #{i_name}_tmp)\n"
435
+ out.write "else\n"
436
+ out.write " run.set_input('#{i_name}', sanitize(#{i_name}_tmp))\n"
437
+ out.write "end\n"
438
+ end
439
+
440
+ # add code to handle results_as_zip input, i.e. create zip file
441
+ out.write "\n# get results_as_zip input and open zip file if appropriate\n"
442
+ # get argument index after workflow inputs
443
+ zip_index = t2_workflow.inputs.size * 2
444
+ out.write "zipped = ARGV[#{zip_index}].chomp == \"yes\"\n"
445
+ out.write 'zip_out = Zip::ZipFile.open("/tmp/#{run.uuid}.zip", Zip::ZipFile::CREATE) if zipped' + "\n"
446
+
447
+ end
448
+
449
+
450
+ # Galaxy's script starting taverna run
451
+ def script_start_run(out)
452
+ out.write <<START_RUN
453
+
454
+
455
+ # start run and wait until it is finished
456
+ run.start
457
+ run.wait(:progress => true)
458
+
459
+ START_RUN
460
+ end
461
+
462
+
463
+ # Galaxy's script output handling
464
+ def script_get_outputs(out, t2_workflow)
465
+ # outputs start after all inputs plus the results_as_zip input
466
+ outputs_start_index = t2_workflow.inputs.size * 2 + 1
467
+ outputs_end_index = outputs_start_index + t2_workflow.outputs.size - 1
468
+ out.write "# get output arguments and associated them with a file\n"
469
+ outputs_start_index.upto(outputs_end_index) do |o|
470
+ out.write "output#{o} = File.open(ARGV[#{o}], \"w\")\n"
471
+ out.write "begin\n"
472
+ out.write " get_outputs(run, false, output#{o}, '" + t2_workflow.outputs[o - outputs_start_index].name.to_s + "', zip_out)\n"
473
+ out.write "rescue Exception => err\n"
474
+ out.write " get_outputs(run, false, output#{o}, '" + t2_workflow.outputs[o - outputs_start_index].name.to_s + ".error', zip_out)\n"
475
+ out.write "ensure\n"
476
+ out.write " output#{o}.close\n"
477
+ out.write "end\n"
478
+ end
479
+
480
+ # close zip file if created when dealing with the inputs
481
+ #--
482
+ # ideally that would semantically belong to a separate method
483
+ out.write "\n# close zip_out (the newly created zip file) if opened\n"
484
+ out.write "zip_out.close if zip_out\n"
485
+
486
+ # dealing with zip output here -- zip arg index is outputs_end_index (last
487
+ # output) plus 1
488
+ out.write "\n# open galaxy zip output and write zip file\n"
489
+ out.write "if zipped\n"
490
+ out.write " galaxy_zip_out = File.open(ARGV[#{outputs_end_index+1}], \"w\")\n"
491
+ out.write " output_zip_file(run.uuid, galaxy_zip_out)\n"
492
+ out.write " galaxy_zip_out.close\n"
493
+ out.write "end\n"
494
+
495
+ end
496
+
497
+
498
+ # Galaxy's script cleaning taverna run
499
+ def script_finish_run(out)
500
+ out.write "\n# delete run\n"
501
+ out.write "run.delete\n"
502
+ end
503
+
504
+
505
+
506
+ # Generates the Galaxy tool's xml file responsible for the UI.
507
+ # TODO: maybe clean arguments -- only xml_out is needed to be passed
508
+ def generate_xml(t2_workflow, xml_out)
509
+ tool_begin_tag(xml_out, xml_out.path.match('([^\/]+)\..*$')[1])
510
+ command_tag(xml_out, t2_workflow, xml_out.path.match('([^\/]+)\..*$')[1] + '.rb')
511
+ inputs_tag(xml_out, t2_workflow.inputs)
512
+ outputs_tag(xml_out, t2_workflow.outputs)
513
+ help_tag(xml_out, t2_workflow)
514
+ tool_end_tag(xml_out)
515
+ end
516
+
517
+
518
+ # Generates the Galaxy tool's script file responsible for talking to the
519
+ # taverna server
520
+ # TODO: maybe clean arguments -- only xml_out is needed to be passed
521
+ def generate_rb(t2_workflow, script_out, t2_server)
522
+ script_preample(script_out)
523
+ script_util_methods(script_out)
524
+ script_create_t2_run(script_out, t2_workflow, t2_server)
525
+ script_init_inputs(script_out, t2_workflow)
526
+ script_start_run(script_out)
527
+ script_get_outputs(script_out, t2_workflow)
528
+ script_finish_run(script_out)
529
+ end
530
+
531
+
532
+ # Populates and returns a _MyExperimentWorkflow_ object (same as in
533
+ # myexperiment-rest) from a local t2flow file.
534
+ def populate_taverna_workflow_from_t2flow(t2flow)
535
+ t2flow_file = File.new(t2flow, "r")
536
+ parsed_t2flow = T2Flow::Parser.new.parse(t2flow_file)
537
+
538
+ wkf_title = parsed_t2flow.name
539
+ wkf_descr = parsed_t2flow.main.annotations.descriptions[0] # gets only the first
540
+ wkf_uploader_uri = parsed_t2flow.main.annotations.authors[0]
541
+ wkf_sources = []
542
+ parsed_t2flow.main.sources.each do |s|
543
+ wkf_sources << MyExperimentIOData.new(:name => s.name,
544
+ :descriptions => s.descriptions ? CGI.escapeHTML(s.descriptions.to_s) : [],
545
+ :examples => s.example_values ? s.example_values : [])
546
+ end
547
+ wkf_sinks = []
548
+ parsed_t2flow.main.sinks.each do |s|
549
+ wkf_sinks << MyExperimentIOData.new(:name => s.name,
550
+ :descriptions => s.descriptions ? CGI.escapeHTML(s.descriptions.to_s) : [],
551
+ :examples => s.example_values ? s.example_values : [])
552
+ end
553
+
554
+ workflow = MyExperimentWorkflow.new(:content_uri => t2flow,
555
+ :title => wkf_title,
556
+ :description => wkf_descr,
557
+ :inputs => wkf_sources,
558
+ :outputs => wkf_sinks,
559
+ :uploader_uri => wkf_uploader_uri)
560
+
561
+ end
562
+
563
+
564
+
565
+ # public methods from here onwards
566
+ public
567
+
568
+ #
569
+ # Generates the two files needed for a Galaxy tool: a configuration
570
+ # file (XML) and a processing file (in our case a ruby script)
571
+ #
572
+ # :call-seq:
573
+ # GalaxyTool.generate() -> nil
574
+ #
575
+ def generate
576
+
577
+ # check the type of workflow source and acquire the appropriate data
578
+ if(config[:wkf_source] == Workflows::MYEXPERIMENT_TAVERNA2)
579
+
580
+ # TODO: check and add auth stuff -- even more unsafe with session cookies
581
+ # since the myexp username/passwd will be saved in the galaxy ruby script
582
+ # for all to see...
583
+
584
+ begin
585
+ # Get workflow data from myexperiment -- a _MyExperimentWorkflow_ object is returned
586
+ @wkf_object = MyExperimentREST::Workflow.from_uri(@config[:params][:url])
587
+ rescue Exception => e
588
+ raise "Problem acquiring workflow data from myExperiment!\n" + e
589
+ end
590
+
591
+ elsif(config[:wkf_source] == Workflows::T2FLOW)
592
+
593
+ begin
594
+ # Get workflow data from t2flow file -- a _MyExperimentWorkflow_ object is returned
595
+ @wkf_object = populate_taverna_workflow_from_t2flow(@config[:params][:t2flow])
596
+ rescue Exception => e
597
+ raise "Problem acquiring workflow data from t2flow file!\n" + e
598
+ end
599
+
600
+ else
601
+ raise "No such workflow source supported!"
602
+ end
603
+
604
+ # if an xml_out file handler was not given provide one with the title as the value
605
+ if @config[:params][:xml_out]
606
+ generate_xml(@wkf_object, @config[:params][:xml_out])
607
+ else
608
+ xml_out = open(@wkf_object.title + ".xml", "w")
609
+ generate_xml(@wkf_object, xml_out)
610
+ xml_out.close
611
+ end
612
+
613
+ # if an rb_out file handler was not given provide one with the title as the value
614
+ if @config[:params][:rb_out]
615
+ generate_rb(@wkf_object, @config[:params][:rb_out], @config[:params][:t2_server])
616
+ else
617
+ rb_out = open(@wkf_object.title + ".rb", "w")
618
+ generate_rb(@wkf_object, rb_out, @config[:params][:t2_server])
619
+ rb_out.close
620
+ end
621
+
622
+
623
+ end
624
+
625
+
626
+ end # class GalaxyTool
627
+
628
+ end # module