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/CHANGES +5 -0
- data/README +1 -1
- data/Rakefile +5 -10
- data/bin/workflow_to_galaxy.rb +58 -65
- data/doc/rdoc/CHANGES.html +10 -3
- data/doc/rdoc/Generator.html +49 -46
- data/doc/rdoc/LICENSE.html +3 -3
- data/doc/rdoc/README.html +4 -4
- data/doc/rdoc/WorkflowToGalaxy.html +33 -3
- data/doc/rdoc/WorkflowToGalaxy/GalaxyTool.html +338 -0
- data/doc/rdoc/WorkflowToGalaxy/Workflows.html +155 -0
- data/doc/rdoc/created.rid +6 -7
- data/doc/rdoc/index.html +6 -6
- data/doc/rdoc/lib/workflow-to-galaxy/constants_rb.html +52 -0
- data/doc/rdoc/lib/workflow-to-galaxy/generator_rb.html +7 -4
- data/doc/rdoc/lib/workflow-to-galaxy_rb.html +4 -2
- data/lib/workflow-to-galaxy.rb +4 -2
- data/lib/workflow-to-galaxy/constants.rb +8 -0
- data/lib/workflow-to-galaxy/galaxy.rb +628 -0
- metadata +22 -20
- data/lib/generator.rb +0 -265
- data/lib/workflow-to-galaxy/generator.rb +0 -511
- data/lib/workflow_to_galaxy.rb +0 -65
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: workflow-to-galaxy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
-
|
10
|
-
version: 0.
|
8
|
+
- 3
|
9
|
+
- 0
|
10
|
+
version: 0.3.0
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Kostas Karasavvas
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-10-13 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: myexperiment-rest
|
@@ -23,14 +23,14 @@ dependencies:
|
|
23
23
|
requirement: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
25
25
|
requirements:
|
26
|
-
- -
|
26
|
+
- - ~>
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
hash:
|
28
|
+
hash: 19
|
29
29
|
segments:
|
30
30
|
- 0
|
31
|
-
-
|
32
|
-
-
|
33
|
-
version: 0.
|
31
|
+
- 3
|
32
|
+
- 0
|
33
|
+
version: 0.3.0
|
34
34
|
type: :runtime
|
35
35
|
version_requirements: *id001
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
|
-
- -
|
42
|
+
- - ~>
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
hash: 23
|
45
45
|
segments:
|
@@ -55,14 +55,14 @@ dependencies:
|
|
55
55
|
requirement: &id003 !ruby/object:Gem::Requirement
|
56
56
|
none: false
|
57
57
|
requirements:
|
58
|
-
- -
|
58
|
+
- - ~>
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
hash:
|
60
|
+
hash: 5
|
61
61
|
segments:
|
62
62
|
- 0
|
63
|
-
-
|
64
|
-
-
|
65
|
-
version: 0.
|
63
|
+
- 6
|
64
|
+
- 1
|
65
|
+
version: 0.6.1
|
66
66
|
type: :runtime
|
67
67
|
version_requirements: *id003
|
68
68
|
- !ruby/object:Gem::Dependency
|
@@ -71,7 +71,7 @@ dependencies:
|
|
71
71
|
requirement: &id004 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
|
-
- -
|
74
|
+
- - ~>
|
75
75
|
- !ruby/object:Gem::Version
|
76
76
|
hash: 51
|
77
77
|
segments:
|
@@ -97,14 +97,15 @@ files:
|
|
97
97
|
- CHANGES
|
98
98
|
- Rakefile
|
99
99
|
- bin/workflow_to_galaxy.rb
|
100
|
-
- lib/
|
101
|
-
- lib/
|
102
|
-
- lib/workflow-to-galaxy/generator.rb
|
100
|
+
- lib/workflow-to-galaxy/galaxy.rb
|
101
|
+
- lib/workflow-to-galaxy/constants.rb
|
103
102
|
- lib/workflow-to-galaxy.rb
|
104
103
|
- doc/rdoc/WorkflowToGalaxy.html
|
105
104
|
- doc/rdoc/rdoc.css
|
106
105
|
- doc/rdoc/Generator.html
|
107
106
|
- doc/rdoc/LICENSE.html
|
107
|
+
- doc/rdoc/WorkflowToGalaxy/Workflows.html
|
108
|
+
- doc/rdoc/WorkflowToGalaxy/GalaxyTool.html
|
108
109
|
- doc/rdoc/index.html
|
109
110
|
- doc/rdoc/js/jquery.js
|
110
111
|
- doc/rdoc/js/thickbox-compressed.js
|
@@ -116,6 +117,7 @@ files:
|
|
116
117
|
- doc/rdoc/lib/workflow-to-galaxy_rb.html
|
117
118
|
- doc/rdoc/lib/generator_rb.html
|
118
119
|
- doc/rdoc/lib/workflow-to-galaxy/generator_rb.html
|
120
|
+
- doc/rdoc/lib/workflow-to-galaxy/constants_rb.html
|
119
121
|
- doc/rdoc/created.rid
|
120
122
|
- doc/rdoc/CHANGES.html
|
121
123
|
- doc/rdoc/images/find.png
|
data/lib/generator.rb
DELETED
@@ -1,265 +0,0 @@
|
|
1
|
-
|
2
|
-
# Contains code to generate the Galaxy's tool xml and script files
|
3
|
-
module Generator
|
4
|
-
|
5
|
-
INDENT = " "
|
6
|
-
|
7
|
-
|
8
|
-
# private methods
|
9
|
-
private
|
10
|
-
|
11
|
-
def tool_b(out, name)
|
12
|
-
out.write("<tool id=\"#{name}_id\" name=\"#{name}\">\n")
|
13
|
-
end
|
14
|
-
|
15
|
-
def command_be(out, me_rest, script)
|
16
|
-
out.write "#{INDENT}<command interpreter=\"ruby\">"
|
17
|
-
out.write script + " "
|
18
|
-
me_rest.workflow.inputs.each do |i|
|
19
|
-
out.write "\"$#{i.name}\" "
|
20
|
-
end
|
21
|
-
me_rest.workflow.outputs.each do |o|
|
22
|
-
out.write "$#{o.name} "
|
23
|
-
end
|
24
|
-
out.write "</command>\n"
|
25
|
-
end
|
26
|
-
|
27
|
-
def inputs_be(out, inputs)
|
28
|
-
out.write "#{INDENT}<inputs>\n"
|
29
|
-
if inputs.size >= 1
|
30
|
-
inputs.each do |i|
|
31
|
-
2.times { out.write "#{INDENT}" }
|
32
|
-
out.write "<param name=\"#{i.name}\" type=\"text\" size=\"30\" "
|
33
|
-
if i.examples.size >= 1
|
34
|
-
# escape double quotes characters for galaxy's xml file
|
35
|
-
ex = i.examples[0].to_s.gsub('"', '"')
|
36
|
-
out.write "value=\"#{ex}\" "
|
37
|
-
end
|
38
|
-
out.write "label=\"Enter #{i.name}\"/>\n"
|
39
|
-
end
|
40
|
-
else
|
41
|
-
2.times { out.write "#{INDENT}" }
|
42
|
-
out.write "<param name=\"input\" type=\"select\" display=\"radio\" size=\"250\" label=\"This workflow has no inputs\" />\n"
|
43
|
-
end
|
44
|
-
out.write "#{INDENT}</inputs>\n"
|
45
|
-
end
|
46
|
-
|
47
|
-
def outputs_be(out, outputs)
|
48
|
-
out.write "#{INDENT}<outputs>\n"
|
49
|
-
outputs.each do |o|
|
50
|
-
2.times { out.write "#{INDENT}" }
|
51
|
-
out.write "<data format=\"tabular\" name=\"#{o.name}\" label=\"#{o.name}\"/>\n"
|
52
|
-
end
|
53
|
-
out.write "#{INDENT}</outputs>\n"
|
54
|
-
end
|
55
|
-
|
56
|
-
def help_be(out, me_rest)
|
57
|
-
out.write "#{INDENT}<help>\n"
|
58
|
-
out.write "**What it does**\n\n"
|
59
|
-
|
60
|
-
# Sometimes the workflow description contains HTML tags that are not allowed
|
61
|
-
# in Galaxy's xml interface specification and thus are removed! Same for
|
62
|
-
# HTML entities!
|
63
|
-
out.write me_rest.workflow.description.gsub(/<.*?>|&.*?;/, '') + "\n\n"
|
64
|
-
|
65
|
-
if me_rest.workflow.inputs.size >= 1
|
66
|
-
out.write "-----\n\n"
|
67
|
-
out.write "**Inputs**\n\n"
|
68
|
-
me_rest.workflow.inputs.each do |i|
|
69
|
-
out.write "- **#{i.name}** "
|
70
|
-
if i.descriptions.size >= 1
|
71
|
-
i.descriptions.each do |desc|
|
72
|
-
out.write desc.to_s + " "
|
73
|
-
end
|
74
|
-
end
|
75
|
-
if i.examples.size >= 1
|
76
|
-
out.write "Examples include:\n\n"
|
77
|
-
i.examples.each do |ex|
|
78
|
-
out.write " - " + ex.to_s + "\n"
|
79
|
-
end
|
80
|
-
end
|
81
|
-
out.write "\n"
|
82
|
-
end
|
83
|
-
out.write "\n"
|
84
|
-
end
|
85
|
-
|
86
|
-
# TODO this code is identical to the inputs code above -- method?
|
87
|
-
if me_rest.workflow.outputs.size >= 1
|
88
|
-
out.write "-----\n\n"
|
89
|
-
out.write "**Outputs**\n\n"
|
90
|
-
me_rest.workflow.outputs.each do |o|
|
91
|
-
out.write "- **#{o.name}** "
|
92
|
-
if o.descriptions.size >= 1
|
93
|
-
o.descriptions.each do |desc|
|
94
|
-
out.write desc.to_s + " "
|
95
|
-
end
|
96
|
-
end
|
97
|
-
if o.examples.size >= 1
|
98
|
-
out.write "Examples include:\n\n"
|
99
|
-
o.examples.each do |ex|
|
100
|
-
out.write " - " + ex.to_s + "\n"
|
101
|
-
end
|
102
|
-
end
|
103
|
-
out.write "\n"
|
104
|
-
end
|
105
|
-
out.write "\n"
|
106
|
-
end
|
107
|
-
|
108
|
-
|
109
|
-
out.write "-----\n\n"
|
110
|
-
out.write "For more information on that workflow please visit #{me_rest.uri.gsub(/(.*workflows\/\d+)[\/.].*/, '\1')}.\n"
|
111
|
-
|
112
|
-
out.write "#{INDENT}</help>\n"
|
113
|
-
end
|
114
|
-
|
115
|
-
def tool_e(out)
|
116
|
-
out.write("</tool>\n")
|
117
|
-
end
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
def script_preample(out)
|
123
|
-
out.write("#!/usr/bin/env ruby\n\n")
|
124
|
-
out.write("require 'rubygems'\n")
|
125
|
-
out.write("require 't2-server'\n")
|
126
|
-
out.write("require 'open-uri'\n\n")
|
127
|
-
end
|
128
|
-
|
129
|
-
def script_util_methods(out)
|
130
|
-
|
131
|
-
out.write <<UTIL_METHODS
|
132
|
-
|
133
|
-
# method that flattens the list of list of list ... result of get_output
|
134
|
-
def print_flattened_result(out, data_lists)
|
135
|
-
data_lists.each do |l|
|
136
|
-
if l.instance_of? Array
|
137
|
-
print_flattened_result(out, l)
|
138
|
-
else
|
139
|
-
out.puts l
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
|
145
|
-
# method that acquires all the results of the specified output
|
146
|
-
def get_outputs(run, refs, outfile, dir)
|
147
|
-
data_lists = run.get_output(dir, refs)
|
148
|
-
print_flattened_result(outfile, data_lists)
|
149
|
-
end
|
150
|
-
|
151
|
-
|
152
|
-
#
|
153
|
-
# Sanitize single and double quotes in str. E.g. galaxy substitures them to
|
154
|
-
# __sq__ and __dq__ respectively. This methods turns them back to their
|
155
|
-
# original values before using them
|
156
|
-
#
|
157
|
-
def sanitize(string)
|
158
|
-
string.gsub(/(__sq__|__dq__|__at__)/) do
|
159
|
-
if $1 == '__sq__'
|
160
|
-
"'"
|
161
|
-
elsif $1 == '__dq__'
|
162
|
-
'\\\"'
|
163
|
-
else
|
164
|
-
'@'
|
165
|
-
end
|
166
|
-
end
|
167
|
-
end
|
168
|
-
|
169
|
-
UTIL_METHODS
|
170
|
-
|
171
|
-
end
|
172
|
-
|
173
|
-
|
174
|
-
def script_create_t2_run(out, wkf_uri, t2_uri)
|
175
|
-
out.write <<CREATE_T2_RUN
|
176
|
-
|
177
|
-
# use the uri reference to download the workflow locally
|
178
|
-
wkf_file = URI.parse('#{wkf_uri}')
|
179
|
-
in_wkf = open(wkf_file)
|
180
|
-
wkf = in_wkf.read()
|
181
|
-
|
182
|
-
# create run
|
183
|
-
begin
|
184
|
-
run = T2Server::Run.create('#{t2_uri}', wkf)
|
185
|
-
rescue T2Server::T2ServerError => e
|
186
|
-
exit 1
|
187
|
-
end
|
188
|
-
|
189
|
-
CREATE_T2_RUN
|
190
|
-
|
191
|
-
end
|
192
|
-
|
193
|
-
|
194
|
-
def script_init_inputs(out, me_rest)
|
195
|
-
out.write "# get input arguments\n"
|
196
|
-
0.upto(me_rest.workflow.inputs.size-1) do |i|
|
197
|
-
out.write "input#{i}_arg = ARGV[#{i}].chomp\n"
|
198
|
-
out.write "run.set_input('" + me_rest.workflow.inputs[i].name.to_s + "', sanitize(input#{i}_arg))\n"
|
199
|
-
end
|
200
|
-
|
201
|
-
end
|
202
|
-
|
203
|
-
|
204
|
-
def script_start_run(out)
|
205
|
-
out.write <<START_RUN
|
206
|
-
|
207
|
-
# start run and wait until it is finished
|
208
|
-
run.start
|
209
|
-
run.wait(:progress => true)
|
210
|
-
|
211
|
-
START_RUN
|
212
|
-
end
|
213
|
-
|
214
|
-
|
215
|
-
def script_get_outputs(out, me_rest)
|
216
|
-
outputs_start_index = me_rest.workflow.inputs.size
|
217
|
-
outputs_end_index = outputs_start_index + me_rest.workflow.outputs.size - 1
|
218
|
-
out.write "# get output arguments and associated them with a file\n"
|
219
|
-
outputs_start_index.upto(outputs_end_index) do |o|
|
220
|
-
out.write "output#{o} = File.open(ARGV[#{o}], \"w\")\n"
|
221
|
-
out.write "get_outputs(run, false, output#{o}, '" + me_rest.workflow.outputs[o - outputs_start_index].name.to_s + "')\n"
|
222
|
-
end
|
223
|
-
|
224
|
-
end
|
225
|
-
|
226
|
-
|
227
|
-
def script_finish_run(out)
|
228
|
-
out.write "\n# delete run\n"
|
229
|
-
out.write "run.delete\n"
|
230
|
-
end
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
# public methods from here onwards
|
235
|
-
public
|
236
|
-
|
237
|
-
# Generates the Galaxy tool's xml file responsible for the UI.
|
238
|
-
def generate_xml(me_rest, xml_file)
|
239
|
-
out = File.open(xml_file, "w")
|
240
|
-
tool_b(out, me_rest.workflow.title)
|
241
|
-
command_be(out, me_rest, xml_file.gsub('.xml', '.rb'))
|
242
|
-
inputs_be(out, me_rest.workflow.inputs)
|
243
|
-
outputs_be(out, me_rest.workflow.outputs)
|
244
|
-
help_be(out, me_rest)
|
245
|
-
tool_e(out)
|
246
|
-
out.close
|
247
|
-
end
|
248
|
-
|
249
|
-
#
|
250
|
-
# Generates the Galaxy tool's script file responsible for talking to the
|
251
|
-
# taverna server
|
252
|
-
#
|
253
|
-
def generate_script(me_rest, t2_server, script_file)
|
254
|
-
out = File.open(script_file, "w")
|
255
|
-
script_preample(out)
|
256
|
-
script_util_methods(out)
|
257
|
-
script_create_t2_run(out, me_rest.uri, t2_server)
|
258
|
-
script_init_inputs(out, me_rest)
|
259
|
-
script_start_run(out)
|
260
|
-
script_get_outputs(out, me_rest)
|
261
|
-
script_finish_run(out)
|
262
|
-
out.close
|
263
|
-
end
|
264
|
-
|
265
|
-
end
|
@@ -1,511 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# The Generator module contains two public methods that generate a Galaxy's tool
|
3
|
-
# XML and script files
|
4
|
-
#--
|
5
|
-
# Add appropriate requires here. Currently they are all in the executable!
|
6
|
-
module Generator
|
7
|
-
|
8
|
-
# private methods
|
9
|
-
private
|
10
|
-
|
11
|
-
# Used to create indentation when generating code
|
12
|
-
def indent(n)
|
13
|
-
ind = ""
|
14
|
-
n.times { ind += " " }
|
15
|
-
ind
|
16
|
-
end
|
17
|
-
|
18
|
-
# Galaxy's XML tool tag
|
19
|
-
def tool_begin_tag(out, name)
|
20
|
-
out.write("<tool id=\"#{name}_id\" name=\"#{name}\">\n")
|
21
|
-
end
|
22
|
-
|
23
|
-
# Galaxy's XML command tag
|
24
|
-
def command_tag(out, t2_workflow, script)
|
25
|
-
out.write indent(1) + "<command interpreter=\"ruby\">\n"
|
26
|
-
out.write indent(2) + script + "\n"
|
27
|
-
|
28
|
-
# inputs
|
29
|
-
t2_workflow.inputs.each do |i|
|
30
|
-
out.write indent(2) + "#if $#{i.name}_source.history_or_textfield == \"textfield\":\n"
|
31
|
-
out.write indent(3) + "false \"$#{i.name}_source.textfield_#{i.name}\"\n"
|
32
|
-
out.write indent(2) + "#else:\n"
|
33
|
-
out.write indent(3) + "true \"$#{i.name}_source.history_#{i.name}\"\n"
|
34
|
-
out.write indent(2) + "#end if\n"
|
35
|
-
end
|
36
|
-
|
37
|
-
# results as zip input
|
38
|
-
out.write indent(2) + "$results_as_zip\n"
|
39
|
-
|
40
|
-
# outputs
|
41
|
-
out.write indent(2)
|
42
|
-
t2_workflow.outputs.each do |o|
|
43
|
-
out.write "$#{o.name} "
|
44
|
-
end
|
45
|
-
|
46
|
-
# result zip output
|
47
|
-
out.write "$result_zip\n"
|
48
|
-
|
49
|
-
out.write indent(1) + "</command>\n"
|
50
|
-
end
|
51
|
-
|
52
|
-
|
53
|
-
# Galaxy's XML inputs tag
|
54
|
-
def inputs_tag(out, inputs)
|
55
|
-
out.write indent(1) + "<inputs>\n"
|
56
|
-
if inputs.size >= 1
|
57
|
-
inputs.each do |i|
|
58
|
-
out.write indent(2) + "<conditional name=\"#{i.name}_source\">\n"
|
59
|
-
out.write indent(3) + "<param name=\"history_or_textfield\" type=\"select\" label=\"Select source for #{i.name}\">\n"
|
60
|
-
out.write indent(4) + "<option value=\"history\">From history</option>\n"
|
61
|
-
out.write indent(4) + "<option value=\"textfield\" selected=\"true\">Type manually</option>\n"
|
62
|
-
out.write indent(3) + "</param>\n"
|
63
|
-
out.write indent(3) + "<when value=\"history\">\n"
|
64
|
-
out.write indent(4) + "<param name=\"history_#{i.name}\" type=\"data\" label=\"Select #{i.name}\"/>\n"
|
65
|
-
out.write indent(3) + "</when>\n"
|
66
|
-
out.write indent(3) + "<when value=\"textfield\">\n"
|
67
|
-
out.write indent(4) + "<param name=\"textfield_#{i.name}\" type=\"text\" area=\"True\" size=\"2x50\" "
|
68
|
-
if i.examples.size >= 1
|
69
|
-
# escape double quotes characters for galaxy's xml file
|
70
|
-
ex = i.examples[0].to_s.gsub('"', '"')
|
71
|
-
# convert newlines to HTML newlines to display in textareas inputs
|
72
|
-
ex = ex.gsub(/[\n]/, '
')
|
73
|
-
out.write "value=\"#{ex}\" "
|
74
|
-
end
|
75
|
-
out.write "label=\"Enter #{i.name}\"/>\n"
|
76
|
-
out.write indent(3) + "</when>\n"
|
77
|
-
out.write indent(2) + "</conditional>\n"
|
78
|
-
end
|
79
|
-
else
|
80
|
-
out.write indent(2) + "<param name=\"input\" type=\"select\" display=\"radio\" size=\"250\" label=\"This workflow has no inputs\" />\n"
|
81
|
-
end
|
82
|
-
|
83
|
-
# result as zip input
|
84
|
-
out.write indent(2) + "<param name=\"results_as_zip\" type=\"select\" label=\"Would you also like the raw results as a zip file\">\n"
|
85
|
-
out.write indent(3) + "<option value=\"yes\">Yes</option>\n"
|
86
|
-
out.write indent(3) + "<option value=\"no\" selected=\"true\">No</option>\n"
|
87
|
-
out.write indent(2) + "</param>\n"
|
88
|
-
|
89
|
-
out.write indent(1) + "</inputs>\n"
|
90
|
-
end
|
91
|
-
|
92
|
-
# Galaxy's XML outputs tag
|
93
|
-
def outputs_tag(out, outputs)
|
94
|
-
out.write indent(1) + "<outputs>\n"
|
95
|
-
outputs.each do |o|
|
96
|
-
out.write indent(2) + "<data format=\"tabular\" name=\"#{o.name}\" label=\"#{o.name}\"/>\n"
|
97
|
-
end
|
98
|
-
|
99
|
-
# result zip output
|
100
|
-
out.write indent(2) + "<data format=\"zip\" name=\"result_zip\" label=\"Compressed Results (zip)\">\n"
|
101
|
-
out.write indent(3) + "<filter>results_as_zip == \"yes\"</filter>\n"
|
102
|
-
out.write indent(2) + "</data>\n"
|
103
|
-
|
104
|
-
out.write indent(1) + "</outputs>\n"
|
105
|
-
end
|
106
|
-
|
107
|
-
# Galaxy's XML help tag
|
108
|
-
def help_tag(out, t2_workflow)
|
109
|
-
out.write indent(1) + "<help>\n"
|
110
|
-
|
111
|
-
if t2_workflow.description
|
112
|
-
out.write "**What it does**\n\n"
|
113
|
-
|
114
|
-
description = t2_workflow.description + "\n\n"
|
115
|
-
|
116
|
-
# Sometimes the workflow description contains HTML tags that are not allowed
|
117
|
-
# in Galaxy's xml interface specification and thus are removed! Same for
|
118
|
-
# HTML entities!
|
119
|
-
# TODO go through tags and find Galaxy's equivalent to include
|
120
|
-
description.gsub!(/<.*?>|&.*?;/, '')
|
121
|
-
|
122
|
-
# To remove ^M (cntl-v + cntl-m) characters that DOS files might have
|
123
|
-
description.gsub!(/\r/, '')
|
124
|
-
|
125
|
-
# TODO that works as a literal too but font changes to courier!
|
126
|
-
#out.write "::\n\n" # Start Galaxy's literal block to ignore indendation
|
127
|
-
|
128
|
-
# remove indendation from all description lines since Galaxy is confused by it
|
129
|
-
description.split(/[\n]/).each { |l| out.write "#{l.gsub(/^\s+/, '')}\n" }
|
130
|
-
|
131
|
-
# endline makes the following be parsed as a Galaxy GUI construct
|
132
|
-
out.write "\n"
|
133
|
-
end
|
134
|
-
|
135
|
-
# if at least one input add it to tool's UI help description
|
136
|
-
if t2_workflow.inputs.size >= 1
|
137
|
-
out.write "-----\n\n"
|
138
|
-
out.write "**Inputs**\n\n"
|
139
|
-
t2_workflow.inputs.each do |i|
|
140
|
-
out.write "- **#{i.name}** "
|
141
|
-
if i.descriptions.size >= 1
|
142
|
-
i.descriptions.each do |desc|
|
143
|
-
out.write desc.to_s + " "
|
144
|
-
end
|
145
|
-
end
|
146
|
-
if i.examples.size >= 1
|
147
|
-
out.write "Examples include:\n\n"
|
148
|
-
i.examples.each do |ex|
|
149
|
-
# some examples have a newline between them that breaks Galaxy's GUI
|
150
|
-
# so we substitute it with ' '
|
151
|
-
#out.write " - " + ex.to_s.gsub(/[\n]/, ' ') + "\n"
|
152
|
-
|
153
|
-
# We could substitute them with with 
 that works for HTML (e.g. wkf 1180)
|
154
|
-
# But if an example input is truly multiline then input descr. will
|
155
|
-
# display them all as separate inputs...
|
156
|
-
out.write " - " + ex.to_s.gsub(/[\n]/, '
 - ') + "\n"
|
157
|
-
|
158
|
-
# display example inputs as verbatim/literal so it is not our responsibility!!
|
159
|
-
# add indendation after each newline to specify the literal block
|
160
|
-
# TODO this looks ugly if we don't remove all the bullet points!
|
161
|
-
#out.write "::\n\n " + ex.to_s.gsub(/\n/, '
 ') + "\n"
|
162
|
-
end
|
163
|
-
end
|
164
|
-
out.write "\n"
|
165
|
-
end
|
166
|
-
out.write "\n"
|
167
|
-
end
|
168
|
-
|
169
|
-
# if at least one output add it to tool's UI help description
|
170
|
-
if t2_workflow.outputs.size >= 1
|
171
|
-
out.write "-----\n\n"
|
172
|
-
out.write "**Outputs**\n\n"
|
173
|
-
t2_workflow.outputs.each do |o|
|
174
|
-
out.write "- **#{o.name}** "
|
175
|
-
if o.descriptions.size >= 1
|
176
|
-
o.descriptions.each do |desc|
|
177
|
-
out.write desc.to_s + " "
|
178
|
-
end
|
179
|
-
end
|
180
|
-
if o.examples.size >= 1
|
181
|
-
out.write "Examples include:\n\n"
|
182
|
-
o.examples.each do |ex|
|
183
|
-
out.write " - " + ex.to_s + "\n"
|
184
|
-
end
|
185
|
-
end
|
186
|
-
out.write "\n"
|
187
|
-
end
|
188
|
-
out.write "\n"
|
189
|
-
end
|
190
|
-
|
191
|
-
out.write "-----\n\n"
|
192
|
-
out.write ".. class:: warningmark\n\n"
|
193
|
-
out.write "**Please note that some workflows are not up-to-date or have dependencies** " <<
|
194
|
-
"that cannot be met by the specific Taverna server that you specified during " <<
|
195
|
-
"generation of this tool. You can make sure that the workflow is valid " <<
|
196
|
-
"by running it in the Taverna Workbench first to confirm that it works " <<
|
197
|
-
"before running it via Galaxy.\n\n"
|
198
|
-
|
199
|
-
if t2_workflow.input_type == TavernaWorkflow::MY_EXPERIMENT
|
200
|
-
out.write "-----\n\n"
|
201
|
-
out.write ".. class:: warningmark\n\n"
|
202
|
-
out.write "**Please note that there might be some repetitions in the workflow description** " <<
|
203
|
-
"in some of the generated workflows. This is due to a backwards compatibility " <<
|
204
|
-
"issue on the myExperiment repository which keeps the old descriptions to make " <<
|
205
|
-
"sure that no information is lost.\n\n"
|
206
|
-
|
207
|
-
out.write "-----\n\n"
|
208
|
-
out.write ".. class:: infomark\n\n"
|
209
|
-
out.write "**For more information on that workflow please visit** #{t2_workflow.xml_uri.gsub(/(.*workflows\/\d+)[\/.].*/, '\1')}.\n\n"
|
210
|
-
end
|
211
|
-
|
212
|
-
out.write indent(1) + "</help>\n"
|
213
|
-
end
|
214
|
-
|
215
|
-
# Galaxy's XML tool tag close
|
216
|
-
def tool_end_tag(out)
|
217
|
-
out.write("</tool>\n")
|
218
|
-
end
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
# Galaxy's script preample
|
223
|
-
def script_preample(out)
|
224
|
-
out.write("#!/usr/bin/env ruby\n\n")
|
225
|
-
|
226
|
-
out.write("# This script can be tested without Galaxy. You can run from the shell as follows:\n#\n")
|
227
|
-
out.write("# $ script_name.rb <input1> true|false <input2> true|false yes|no <output1> <output2>\n#\n")
|
228
|
-
out.write("# After each input value a boolean specifies if the value is literal (false) or if\n")
|
229
|
-
out.write("# it specifies a file name to read as input.\n#\n")
|
230
|
-
out.write("# After all workflow inputs a yes or no input specifies if we also want our results zipped.\n#\n")
|
231
|
-
out.write("# Finally, all the output files follow. Note that if you selected to also get a zip\n")
|
232
|
-
out.write("# then you need to specify an additional output in the end after the normal workflow\n")
|
233
|
-
out.write("# outputs.\n\n")
|
234
|
-
|
235
|
-
out.write("require 'rubygems'\n")
|
236
|
-
out.write("require 't2-server'\n")
|
237
|
-
out.write("require 'open-uri'\n")
|
238
|
-
out.write("require 'zip/zipfilesystem'\n\n")
|
239
|
-
end
|
240
|
-
|
241
|
-
|
242
|
-
# Galaxy's script utility methods
|
243
|
-
# TODO: use ruby's flatten instead of our own !!!
|
244
|
-
def script_util_methods(out)
|
245
|
-
|
246
|
-
out.write <<'UTIL_METHODS'
|
247
|
-
|
248
|
-
# sends the zip file to specified output
|
249
|
-
def output_zip_file(uuid, zip_out)
|
250
|
-
File.open("/tmp/#{uuid}.zip") do |zip|
|
251
|
-
while data = zip.read(4096)
|
252
|
-
zip_out.write data
|
253
|
-
end
|
254
|
-
end
|
255
|
-
File.delete("/tmp/#{uuid}.zip")
|
256
|
-
end
|
257
|
-
|
258
|
-
|
259
|
-
#
|
260
|
-
# replicates the directory result structure as constructed by the
|
261
|
-
# taverna server and recreates it in a zip File
|
262
|
-
#
|
263
|
-
def add_to_zip_file(output_dir, data_lists, zip_out)
|
264
|
-
zip_out.dir.mkdir("#{output_dir}")
|
265
|
-
data_lists.each_with_index do |item, index|
|
266
|
-
if item.instance_of? Array
|
267
|
-
add_to_zip_file("#{output_dir}/#{index+1}", item, zip_out)
|
268
|
-
else
|
269
|
-
zip_out.file.open("#{output_dir}/#{index+1}", "w") { |f| f.puts item }
|
270
|
-
end
|
271
|
-
end
|
272
|
-
end
|
273
|
-
|
274
|
-
|
275
|
-
# method that flattens the list of list of list ... result of get_output
|
276
|
-
def print_flattened_result(out, data_lists)
|
277
|
-
data_lists.each do |l|
|
278
|
-
if l.instance_of? Array
|
279
|
-
print_flattened_result(out, l)
|
280
|
-
else
|
281
|
-
out.puts l
|
282
|
-
end
|
283
|
-
end
|
284
|
-
end
|
285
|
-
|
286
|
-
|
287
|
-
#
|
288
|
-
# Method that acquires all the results of the specified output directory.
|
289
|
-
# If valid zip File is passed it also accumulates results as a zip file.
|
290
|
-
#
|
291
|
-
def get_outputs(run, refs, outfile, dir, zip_out=nil)
|
292
|
-
data_lists = run.get_output(dir, refs)
|
293
|
-
print_flattened_result(outfile, data_lists)
|
294
|
-
if zip_out
|
295
|
-
add_to_zip_file(dir, data_lists, zip_out)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
|
299
|
-
|
300
|
-
#
|
301
|
-
# Sanitize all special characters in UI inputs that Galaxy substitutes for
|
302
|
-
# security reasons. This methods turns them back to their original values before
|
303
|
-
# using them (i.e. sending them to the taverna server
|
304
|
-
# NB: note that double quote is sanitized to "'" that is because the double code
|
305
|
-
# confuses the Taverna server ruby library. Apparently, this is not trivial
|
306
|
-
# to fix.
|
307
|
-
#
|
308
|
-
def sanitize(string)
|
309
|
-
string.gsub(/(__sq__|__dq__|__at__|__cr__|__cn__|__tc__|__gt__|__lt__|__ob__|__cb__|__oc__|__cc__)/) do
|
310
|
-
if $1 == '__sq__'
|
311
|
-
"'"
|
312
|
-
elsif $1 == '__dq__'
|
313
|
-
"'"
|
314
|
-
elsif $1 == '__cr__'
|
315
|
-
"\r"
|
316
|
-
elsif $1 == '__cn__'
|
317
|
-
"\n"
|
318
|
-
elsif $1 == '__tc__'
|
319
|
-
"\t"
|
320
|
-
elsif $1 == '__gt__'
|
321
|
-
'>'
|
322
|
-
elsif $1 == '__lt__'
|
323
|
-
'<'
|
324
|
-
elsif $1 == '__ob__'
|
325
|
-
'['
|
326
|
-
elsif $1 == '__cb__'
|
327
|
-
']'
|
328
|
-
elsif $1 == '__oc__'
|
329
|
-
'{'
|
330
|
-
elsif $1 == '__cc__'
|
331
|
-
'}'
|
332
|
-
else
|
333
|
-
'@'
|
334
|
-
end
|
335
|
-
end
|
336
|
-
end
|
337
|
-
|
338
|
-
#
|
339
|
-
# Deletes last new line of file if it exists! It is needed for t2 workflows that
|
340
|
-
# do not sanitize properly, i.e. via a user-provided beanshell script
|
341
|
-
#
|
342
|
-
def chomp_last_newline(file)
|
343
|
-
|
344
|
-
if File.file?(file) and File.size(file) > 1
|
345
|
-
f = open(file, "rb+")
|
346
|
-
f.seek(-1, File::SEEK_END)
|
347
|
-
f.truncate(File.size(file) - 1) if f.read(1) == "\n"
|
348
|
-
f.close
|
349
|
-
end
|
350
|
-
|
351
|
-
end
|
352
|
-
|
353
|
-
|
354
|
-
UTIL_METHODS
|
355
|
-
|
356
|
-
end
|
357
|
-
|
358
|
-
# Galaxy's script taverna 2 run
|
359
|
-
def script_create_t2_run(out, wkf, t2_uri)
|
360
|
-
if wkf.input_type == TavernaWorkflow::MY_EXPERIMENT
|
361
|
-
out.write "# use the uri reference to download the workflow locally\n"
|
362
|
-
out.write "wkf_file = URI.parse('#{wkf.xml_uri}')\n"
|
363
|
-
out.write "in_wkf = open(wkf_file)\n"
|
364
|
-
else # TavernaWorkflow::T2_FLOW
|
365
|
-
out.write "# uri contains local t2flow file\n"
|
366
|
-
out.write "in_wkf = open('#{wkf.xml_uri}')\n"
|
367
|
-
end
|
368
|
-
|
369
|
-
out.write <<CREATE_T2_RUN
|
370
|
-
|
371
|
-
wkf = in_wkf.read()
|
372
|
-
|
373
|
-
# create run
|
374
|
-
begin
|
375
|
-
run = T2Server::Run.create('#{t2_uri}', wkf)
|
376
|
-
rescue T2Server::T2ServerError => e
|
377
|
-
exit 1
|
378
|
-
end
|
379
|
-
|
380
|
-
CREATE_T2_RUN
|
381
|
-
|
382
|
-
end
|
383
|
-
|
384
|
-
|
385
|
-
# Galaxy's script input handling
|
386
|
-
def script_init_inputs(out, t2_workflow)
|
387
|
-
out.write "#\n"
|
388
|
-
out.write "# Get input arguments -- for each input a boolean specifies if it's from history\n"
|
389
|
-
out.write "# thus, for each t2_workflow input we have two arguments in the script!\n"
|
390
|
-
out.write "#\n"
|
391
|
-
t2_workflow.inputs.each_with_index do |input, i|
|
392
|
-
i_name = input.name.to_s
|
393
|
-
out.write "#{i_name}_from_history = ARGV[#{i*2}].chomp\n"
|
394
|
-
out.write "#{i_name}_tmp = ARGV[#{i*2+1}].chomp\n"
|
395
|
-
out.write "if #{i_name}_from_history == \"true\"\n"
|
396
|
-
out.write " chomp_last_newline(#{i_name}_tmp)\n"
|
397
|
-
out.write " run.upload_input_file('#{i_name}', #{i_name}_tmp)\n"
|
398
|
-
out.write "else\n"
|
399
|
-
out.write " run.set_input('#{i_name}', sanitize(#{i_name}_tmp))\n"
|
400
|
-
out.write "end\n"
|
401
|
-
end
|
402
|
-
|
403
|
-
# add code to handle results_as_zip input, i.e. create zip file
|
404
|
-
out.write "\n# get results_as_zip input and open zip file if appropriate\n"
|
405
|
-
# get argument index after workflow inputs
|
406
|
-
zip_index = t2_workflow.inputs.size * 2
|
407
|
-
out.write "zipped = ARGV[#{zip_index}].chomp == \"yes\"\n"
|
408
|
-
out.write 'zip_out = Zip::ZipFile.open("/tmp/#{run.uuid}.zip", Zip::ZipFile::CREATE) if zipped' + "\n"
|
409
|
-
|
410
|
-
end
|
411
|
-
|
412
|
-
|
413
|
-
# Galaxy's script starting taverna run
|
414
|
-
def script_start_run(out)
|
415
|
-
out.write <<START_RUN
|
416
|
-
|
417
|
-
|
418
|
-
# start run and wait until it is finished
|
419
|
-
run.start
|
420
|
-
run.wait(:progress => true)
|
421
|
-
|
422
|
-
START_RUN
|
423
|
-
end
|
424
|
-
|
425
|
-
|
426
|
-
# Galaxy's script output handling
|
427
|
-
def script_get_outputs(out, t2_workflow)
|
428
|
-
# outputs start after all inputs plus the results_as_zip input
|
429
|
-
outputs_start_index = t2_workflow.inputs.size * 2 + 1
|
430
|
-
outputs_end_index = outputs_start_index + t2_workflow.outputs.size - 1
|
431
|
-
out.write "# get output arguments and associated them with a file\n"
|
432
|
-
outputs_start_index.upto(outputs_end_index) do |o|
|
433
|
-
out.write "output#{o} = File.open(ARGV[#{o}], \"w\")\n"
|
434
|
-
out.write "begin\n"
|
435
|
-
out.write " get_outputs(run, false, output#{o}, '" + t2_workflow.outputs[o - outputs_start_index].name.to_s + "', zip_out)\n"
|
436
|
-
out.write "rescue Exception => err\n"
|
437
|
-
out.write " get_outputs(run, false, output#{o}, '" + t2_workflow.outputs[o - outputs_start_index].name.to_s + ".error', zip_out)\n"
|
438
|
-
out.write "ensure\n"
|
439
|
-
out.write " output#{o}.close\n"
|
440
|
-
out.write "end\n"
|
441
|
-
end
|
442
|
-
|
443
|
-
# close zip file if created when dealing with the inputs
|
444
|
-
#--
|
445
|
-
# ideally that would semantically belong to a separate method
|
446
|
-
out.write "\n# close zip_out (the newly created zip file) if opened\n"
|
447
|
-
out.write "zip_out.close if zip_out\n"
|
448
|
-
|
449
|
-
# dealing with zip output here -- zip arg index is outputs_end_index (last
|
450
|
-
# output) plus 1
|
451
|
-
out.write "\n# open galaxy zip output and write zip file\n"
|
452
|
-
out.write "if zipped\n"
|
453
|
-
out.write " galaxy_zip_out = File.open(ARGV[#{outputs_end_index+1}], \"w\")\n"
|
454
|
-
out.write " output_zip_file(run.uuid, galaxy_zip_out)\n"
|
455
|
-
out.write " galaxy_zip_out.close\n"
|
456
|
-
out.write "end\n"
|
457
|
-
|
458
|
-
end
|
459
|
-
|
460
|
-
|
461
|
-
# Galaxy's script cleaning taverna run
|
462
|
-
def script_finish_run(out)
|
463
|
-
out.write "\n# delete run\n"
|
464
|
-
out.write "run.delete\n"
|
465
|
-
end
|
466
|
-
|
467
|
-
|
468
|
-
|
469
|
-
|
470
|
-
|
471
|
-
# public methods from here onwards
|
472
|
-
public
|
473
|
-
|
474
|
-
# Generates the Galaxy tool's xml file responsible for the UI.
|
475
|
-
#
|
476
|
-
# :call-seq:
|
477
|
-
# Generator.generate_xml(my_exp_rest, xml_file) -> nil
|
478
|
-
#
|
479
|
-
# [+t2_workflow+] a _Workflow_ object as returned from <em>MyExperimentREST::Workflows.new.read(url)</em>
|
480
|
-
# [+xml_file+] a string containing the name of the generated XML file
|
481
|
-
# [+xml_out+] the file handler to write the generated XML tags
|
482
|
-
def generate_xml(t2_workflow, xml_file, xml_out)
|
483
|
-
tool_begin_tag(xml_out, t2_workflow.title)
|
484
|
-
command_tag(xml_out, t2_workflow, xml_file.gsub('.xml', '.rb'))
|
485
|
-
inputs_tag(xml_out, t2_workflow.inputs)
|
486
|
-
outputs_tag(xml_out, t2_workflow.outputs)
|
487
|
-
help_tag(xml_out, t2_workflow)
|
488
|
-
tool_end_tag(xml_out)
|
489
|
-
end
|
490
|
-
|
491
|
-
|
492
|
-
# Generates the Galaxy tool's script file responsible for talking to the
|
493
|
-
# taverna server
|
494
|
-
#
|
495
|
-
# :call-seq:
|
496
|
-
# Generator.generate_script(my_exp_rest, t2_server, script_file) -> nil
|
497
|
-
#
|
498
|
-
# [+my_exp_rest+] a _Workflow_ object as returned from <em>MyExperimentREST.ReadWorkflow.new(url)</em>
|
499
|
-
# [<tt>t2_server</tt>] a string containing the URL of the taverna 2 server
|
500
|
-
# [+script_out+] the file handler to write the generated script code
|
501
|
-
def generate_script(t2_workflow, t2_server, script_out)
|
502
|
-
script_preample(script_out)
|
503
|
-
script_util_methods(script_out)
|
504
|
-
script_create_t2_run(script_out, t2_workflow, t2_server)
|
505
|
-
script_init_inputs(script_out, t2_workflow)
|
506
|
-
script_start_run(script_out)
|
507
|
-
script_get_outputs(script_out, t2_workflow)
|
508
|
-
script_finish_run(script_out)
|
509
|
-
end
|
510
|
-
|
511
|
-
end
|