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