root/galaxy-taverna/workflow-to-galaxy/lib/workflow-to-galaxy/generator.rb @ 66

Revision 66, 6.7 KB (checked in by kostas.karasavvas@…, 3 years ago)

major restructuring, now doc work properly, lib can be required as expected, etc..

Line 
1
2# Contains code to generate the Galaxy's tool xml and script files
3module 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
169UTIL_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
178wkf_file = URI.parse('#{wkf_uri}')
179in_wkf = open(wkf_file)
180wkf = in_wkf.read()
181
182# create run
183begin
184  run = T2Server::Run.create('#{t2_uri}', wkf)
185rescue T2Server::T2ServerError => e
186  exit 1
187end
188
189CREATE_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
208run.start
209run.wait(:progress => true)
210
211START_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
265end
Note: See TracBrowser for help on using the browser.