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/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
|