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.
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: 5
4
+ hash: 19
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 2
9
- - 9
10
- version: 0.2.9
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-07-26 00:00:00 Z
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: 27
28
+ hash: 19
29
29
  segments:
30
30
  - 0
31
- - 2
32
- - 6
33
- version: 0.2.6
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: 13
60
+ hash: 5
61
61
  segments:
62
62
  - 0
63
- - 5
64
- - 3
65
- version: 0.5.3
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/workflow_to_galaxy.rb
101
- - lib/generator.rb
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('"', '&quot;')
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('"', '&quot;')
71
- # convert newlines to HTML newlines to display in textareas inputs
72
- ex = ex.gsub(/[\n]/, '&#xA;')
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 &#xA; 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]/, '&#xA; - ') + "\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/, '&#xA; ') + "\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