workflow-to-galaxy 0.2.9 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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