taverna-player 0.2.1 → 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.rdoc +10 -0
- data/README.rdoc +92 -53
- data/Rakefile +1 -1
- data/app/helpers/taverna_player/runs_helper.rb +0 -59
- data/app/models/taverna_player/run_port.rb +33 -1
- data/app/views/taverna_player/runs/_outputs.html.erb +1 -1
- data/app/views/taverna_player/runs/embedded/_outputs.html.erb +1 -1
- data/lib/generators/taverna_player/install_generator.rb +1 -1
- data/lib/generators/templates/ReadMe.txt +3 -3
- data/lib/generators/templates/callbacks/render_callbacks.rb +43 -15
- data/lib/generators/templates/player_initializer.rb +11 -7
- data/lib/taverna-player.rb +17 -16
- data/lib/taverna_player/concerns/callback.rb +29 -0
- data/lib/taverna_player/concerns/controllers/runs_controller.rb +4 -8
- data/lib/taverna_player/concerns/models/run_port.rb +24 -3
- data/lib/taverna_player/concerns/utils.rb +30 -0
- data/lib/taverna_player/{output_renderer.rb → port_renderer.rb} +26 -14
- data/lib/taverna_player/render_callbacks.rb +33 -12
- data/lib/taverna_player/version.rb +1 -1
- data/lib/taverna_player/worker.rb +5 -12
- data/test/dummy/config/initializers/{taverna_server.example.rb → taverna_server.rb.example} +0 -0
- data/test/functional/taverna_player/runs_controller_test.rb +11 -6
- data/test/unit/helpers/taverna_player/runs_helper_test.rb +0 -26
- metadata +9 -7
data/CHANGES.rdoc
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
= Changes log for Taverna Player
|
2
2
|
|
3
|
+
== Version 0.3.0
|
4
|
+
|
5
|
+
* Refactor callback code out into its own module.
|
6
|
+
* Fix classname typo in port model templates.
|
7
|
+
* Enable getting deep list outputs from the port models.
|
8
|
+
* Add a method to get a route (path) to a port.
|
9
|
+
* [TAV-465] Refactor renderers and add list rendering.
|
10
|
+
* Factor out common list handling code for sharing.
|
11
|
+
* Rename and re-document renderers.
|
12
|
+
|
3
13
|
== Version 0.2.1
|
4
14
|
|
5
15
|
* Fix classname typo in port model templates.
|
data/README.rdoc
CHANGED
@@ -172,9 +172,9 @@ They will be saved to <tt>lib/taverna_player_callbacks.rb</tt>. Don't forget to
|
|
172
172
|
then require and register them in the Taverna Player initializer. There is more
|
173
173
|
information on callbacks below.
|
174
174
|
|
175
|
-
You can add to, or change, the workflow
|
176
|
-
|
177
|
-
|
175
|
+
You can add to, or change, the workflow port render methods to better suit
|
176
|
+
your particular application. To copy the defaults that Taverna Player ships
|
177
|
+
with into your application for customization run:
|
178
178
|
|
179
179
|
rails generate taverna_player:renderers
|
180
180
|
|
@@ -182,12 +182,19 @@ They will be saved to <tt>lib/taverna_player_renderers.rb</tt>. Don't forget to
|
|
182
182
|
then require and register them in the Taverna Player initializer. There is more
|
183
183
|
information on renderers below.
|
184
184
|
|
185
|
-
== Taverna Player
|
185
|
+
== Taverna Player initializers
|
186
186
|
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
187
|
+
Two initializers are installed by the install generator:
|
188
|
+
* {taverna_player.rb}[https://github.com/myGrid/taverna-player/blob/master/lib/generators/templates/player_initializer.rb]:
|
189
|
+
This contains configuration of Taverna Player.
|
190
|
+
* {taverna_server.rb.example}[https://github.com/myGrid/taverna-player/blob/master/lib/generators/templates/server_initializer.rb]:
|
191
|
+
This is used to configure Taverna Player's connection to a Taverna Server.
|
192
|
+
It is initially set up as an example file as you will need to distribute
|
193
|
+
this with your application but you must not check in the contents of the
|
194
|
+
configured version to your repository.
|
195
|
+
|
196
|
+
Both of these files require minimal configuration for simple set ups and are
|
197
|
+
fully commented with everything that needs to be set - more details below.
|
191
198
|
|
192
199
|
=== Essential (required) configuration
|
193
200
|
|
@@ -332,6 +339,9 @@ your own needs.
|
|
332
339
|
|
333
340
|
You can override the following core components:
|
334
341
|
* Run (model)
|
342
|
+
* RunPort (model)
|
343
|
+
* RunPort::Input (model)
|
344
|
+
* RunPort::Output (model)
|
335
345
|
* RunsController
|
336
346
|
* ServiceCredentialsController
|
337
347
|
|
@@ -405,28 +415,24 @@ A set of example callbacks can be installed with the generator detailed above.
|
|
405
415
|
Don't forget to make sure any callback code is <tt>require</tt>d somewhere and
|
406
416
|
the callbacks themselves registered in the initializer.
|
407
417
|
|
408
|
-
== Rendering
|
409
|
-
|
410
|
-
Workflows can produce results in many different formats and Taverna Player
|
411
|
-
tries to accomodate this as best it can. It provides basic facilities for
|
412
|
-
rendering as many result types as it can and these are extendible wherever
|
413
|
-
possible.
|
418
|
+
== Rendering workflow ports
|
414
419
|
|
415
|
-
|
420
|
+
Workflows can accept inputs and produce results in many different formats and
|
421
|
+
Taverna Player tries to accomodate this as best it can. It provides basic
|
422
|
+
facilities for rendering as many types as it can and these are extensible
|
423
|
+
wherever possible.
|
416
424
|
|
417
|
-
|
418
|
-
|
419
|
-
a generic way. If it is a singleton output then it is displayed normally. If it
|
420
|
-
is a list output then the list is rendered as a HTML ordered list
|
421
|
-
(<tt><ol></tt>).
|
425
|
+
Calling the port renderer is as simple as just passing it the port to be
|
426
|
+
rendered in your view.
|
422
427
|
|
423
|
-
|
424
|
-
|
428
|
+
<% run.outputs.each do |output| %>
|
429
|
+
<%= TavernaPlayer.port_renderer.render(output) %>
|
430
|
+
<% end %>
|
425
431
|
|
426
432
|
=== Type renderers
|
427
433
|
|
428
434
|
Taverna Player has a system of specific type renderers to handle different
|
429
|
-
types of
|
435
|
+
types of value. A number of defaults are supplied but these can be replaced
|
430
436
|
and added to if required.
|
431
437
|
|
432
438
|
To install a set of example renderers you can use the generator detailed above.
|
@@ -434,22 +440,22 @@ To install a set of example renderers you can use the generator detailed above.
|
|
434
440
|
To register a renderer for use add it into the renderers block in the
|
435
441
|
initializer:
|
436
442
|
|
437
|
-
config.
|
443
|
+
config.port_renderers do |renderers|
|
438
444
|
...
|
439
445
|
end
|
440
446
|
|
441
447
|
So to just register a single default renderer method (called
|
442
448
|
"my_default_renderer") you would do this:
|
443
449
|
|
444
|
-
config.
|
450
|
+
config.port_renderers do |renderers|
|
445
451
|
renderers.default(:my_default_renderer)
|
446
452
|
end
|
447
453
|
|
448
|
-
And it would be used to render every type of
|
454
|
+
And it would be used to render every type of value. A more sensible example
|
449
455
|
would be to have a renderer for PNG-type images and a renderer for text
|
450
|
-
|
456
|
+
values as well:
|
451
457
|
|
452
|
-
config.
|
458
|
+
config.port_renderers do |renderers|
|
453
459
|
renderers.default(:my_default_renderer)
|
454
460
|
renderers.add("text/plain", :text_renderer, true)
|
455
461
|
renderers.add("image/png", :show_image)
|
@@ -458,16 +464,16 @@ outputs as well:
|
|
458
464
|
This does three things:
|
459
465
|
* Registers a renderer for PNG images. This could be as simple as wrapping it
|
460
466
|
in an <tt><img ../></tt> tag.
|
461
|
-
* Registers a renderer for
|
467
|
+
* Registers a renderer for values of type "text/plain" and <em>sets this as
|
462
468
|
the default renderer for all other types beginning with "text"</em>. That is
|
463
469
|
what the final parameter set to +true+ does.
|
464
470
|
* Registers a default renderer for all other types. This should probably give
|
465
|
-
an explanation as to why the
|
466
|
-
link to download the
|
471
|
+
an explanation as to why the value cannot be shown in the browser with a
|
472
|
+
link to download the value to the user's computer.
|
467
473
|
|
468
474
|
Note the use of MIME types for specifying all types.
|
469
475
|
|
470
|
-
Obviously
|
476
|
+
Obviously values such as images and text are so common that Taverna Player
|
471
477
|
provides these renderers for you and has them set up and registered by default.
|
472
478
|
You would only need to override them if you wanted extra information to be
|
473
479
|
displayed as well, such as sizes next to images, etc.
|
@@ -485,22 +491,20 @@ show:
|
|
485
491
|
|
486
492
|
Note that the same renderer callback is used for each one.
|
487
493
|
|
488
|
-
===
|
494
|
+
=== Rendering lists
|
489
495
|
|
490
|
-
|
491
|
-
1. The content to be rendered.
|
492
|
-
1. The MIME type of the content.
|
496
|
+
Taverna workflow inputs and output can be lists and rendering them requires a
|
493
497
|
|
494
|
-
|
495
|
-
helper you use, described above) be the entire text content of the output. In
|
496
|
-
most other cases it will probably be a URI or path to the actual content for
|
497
|
-
use in, for example, an <tt><img .../></tt> tag.
|
498
|
+
=== Writing your own renderers
|
498
499
|
|
499
|
-
|
500
|
-
|
500
|
+
To be a renderer callback a method must accept two parameters (in this order):
|
501
|
+
1. The port to be rendered.
|
502
|
+
1. A list of indices into the port. For a singleton port this will be an empty
|
503
|
+
list. For a port of depth 2 this would be a list with two items, e.g.
|
504
|
+
<tt>[0, 0]</tt>
|
501
505
|
|
502
|
-
|
503
|
-
|
506
|
+
All renderer callbacks are called by Taverna Player in a context that includes
|
507
|
+
the {ActionView::Helpers}[http://api.rubyonrails.org/classes/ActionView/Helpers.html]
|
504
508
|
so your callbacks have access to them too, including helpers from third-party
|
505
509
|
gems that register their helpers correctly.
|
506
510
|
|
@@ -515,9 +519,9 @@ Taverna Player provides a plain text renderer that formats text with a
|
|
515
519
|
monospaced font, converts URI-like things to clickable links and respects
|
516
520
|
carriage returns and newlines. It looks something like this:
|
517
521
|
|
518
|
-
def format_text(
|
522
|
+
def format_text(port, index = [])
|
519
523
|
# Use CodeRay to format text so that newlines are respected.
|
520
|
-
content = CodeRay.scan(
|
524
|
+
content = CodeRay.scan(port.value(index), :text).div(:css => :class)
|
521
525
|
|
522
526
|
# Use auto_link to turn URI-like text into links.
|
523
527
|
auto_link(content, :html => { :target => '_blank' }, :sanitize => false)
|
@@ -534,10 +538,10 @@ This renderer is registered as the default for all "text" media types.
|
|
534
538
|
|
535
539
|
This renderer catches "text/XML" outputs:
|
536
540
|
|
537
|
-
def format_xml(
|
541
|
+
def format_xml(port, index = [])
|
538
542
|
# Make sure XML is indented consistently.
|
539
543
|
out = String.new
|
540
|
-
REXML::Document.new(
|
544
|
+
REXML::Document.new(port.value(index)).write(out, 1)
|
541
545
|
CodeRay.scan(out, :xml).div(:css => :class, :line_numbers => :table)
|
542
546
|
end
|
543
547
|
|
@@ -554,24 +558,59 @@ the XML declaration, e.g.:
|
|
554
558
|
|
555
559
|
As described above, images are just dropped into an <tt><img ../></tt> tag:
|
556
560
|
|
557
|
-
def show_image(
|
561
|
+
def show_image(port, index = [])
|
558
562
|
# Can't use image_tag() here because the image doesn't really exist (it's
|
559
563
|
# in a zip file, really) and this confuses the Rails asset pipeline.
|
560
|
-
tag("img", :src =>
|
564
|
+
tag("img", :src => port.path(index))
|
561
565
|
end
|
562
566
|
|
563
567
|
Note the comment about the Rails asset pipeline in there if you are writing
|
564
568
|
your own image renderer and are using the asset pipeline.
|
565
569
|
|
566
|
-
|
570
|
+
==== Lists
|
571
|
+
|
572
|
+
Unless you can be absolutely sure that the workflows that will be run within
|
573
|
+
your installation of Taverna Player will only have lists of a certain depth
|
574
|
+
the lists renderer will need to be able to cope with anything that is thrown
|
575
|
+
at it. The supplied renderer uses recursion to cope with what could, at least
|
576
|
+
in theory, be infinitely deep lists:
|
577
|
+
|
578
|
+
def list_port(port, index = [], types = nil)
|
579
|
+
types = port.metadata[:type] if types.nil?
|
580
|
+
|
581
|
+
content = "<ol>"
|
582
|
+
i = 0
|
583
|
+
types.each do |type|
|
584
|
+
if type.is_a?(Array)
|
585
|
+
content += "<li><br />" +
|
586
|
+
list_port(port, index + [i], type) + "</li>"
|
587
|
+
else
|
588
|
+
content += "<li>(#{type})<p>" +
|
589
|
+
TavernaPlayer.port_renderer.render(port, index + [i]) +
|
590
|
+
"</p></li>"
|
591
|
+
end
|
592
|
+
i += 1
|
593
|
+
end
|
594
|
+
|
595
|
+
content += "</ol>"
|
596
|
+
end
|
597
|
+
|
598
|
+
This method has an extra parameter that is used to drive the recursion. The
|
599
|
+
+types+ parameter contains the list structure of the whole port so can be used
|
600
|
+
to loop over, or recurse into, each level as required.
|
601
|
+
|
602
|
+
Lists are simply rendered as a numbered list along with their type
|
603
|
+
information. Other registered renderers are called as necessary to render
|
604
|
+
individual values.
|
567
605
|
|
568
606
|
==== Other types catch-all
|
569
607
|
|
570
608
|
The default renderer for other, or unknown types, is:
|
571
609
|
|
572
|
-
def cannot_inline(
|
610
|
+
def cannot_inline(port, index = [])
|
573
611
|
"Sorry but we cannot show this type of content in the browser. Please " +
|
574
|
-
link_to("download it",
|
612
|
+
link_to("download it", port.path(index)) + " to view it on your " +
|
613
|
+
"local machine."
|
575
614
|
end
|
576
615
|
|
577
616
|
== Service Credentials
|
data/Rakefile
CHANGED
@@ -40,7 +40,7 @@ RDoc::Task.new(:rdoc) do |rdoc|
|
|
40
40
|
"app/models/taverna_player/run_port.rb",
|
41
41
|
"app/models/taverna_player/service_credential.rb",
|
42
42
|
"lib/taverna-player.rb",
|
43
|
-
"lib/taverna_player/
|
43
|
+
"lib/taverna_player/port_renderer.rb"
|
44
44
|
]
|
45
45
|
|
46
46
|
rdoc.rdoc_files.include(files)
|
@@ -21,64 +21,5 @@ module TavernaPlayer
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
24
|
-
def show_output(run, output)
|
25
|
-
if output.depth == 0
|
26
|
-
if output.value.blank?
|
27
|
-
content = run_path(output.run_id) + "/output/#{output.name}"
|
28
|
-
else
|
29
|
-
if output.metadata[:size] < 255
|
30
|
-
content = output.value
|
31
|
-
else
|
32
|
-
Zip::ZipFile.open(run.results.path) do |zip|
|
33
|
-
content = zip.read(output.name)
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
37
|
-
raw(TavernaPlayer.output_renderer.render(content, output.metadata[:type]))
|
38
|
-
else
|
39
|
-
parse_port_list(run, output)
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
|
45
|
-
def parse_port_list(run, output)
|
46
|
-
types = output.metadata[:type]
|
47
|
-
content = String.new
|
48
|
-
|
49
|
-
Zip::ZipFile.open(run.results.path) do |zip|
|
50
|
-
content = deep_parse(types, output, zip)
|
51
|
-
end
|
52
|
-
|
53
|
-
content
|
54
|
-
end
|
55
|
-
|
56
|
-
def deep_parse(types, output, zip, index = [])
|
57
|
-
content = "<ol>"
|
58
|
-
i = 0
|
59
|
-
types.each do |type|
|
60
|
-
if type.is_a?(Array)
|
61
|
-
content += "<li><br />" +
|
62
|
-
deep_parse(type, output, zip, index + [i]) + "</li>"
|
63
|
-
else
|
64
|
-
# Text outputs are inlined here by us. Other types are linked and
|
65
|
-
# inlined by the browser.
|
66
|
-
content += "<li>(#{type})<p>"
|
67
|
-
if type.starts_with?("text")
|
68
|
-
path = (index + [i]).map { |j| j += 1 }.join("/")
|
69
|
-
data = zip.read("#{output.name}/#{path}")
|
70
|
-
else
|
71
|
-
path = (index + [i]).join("/")
|
72
|
-
data = run_path(output.run_id) + "/output/#{output.name}/#{path}"
|
73
|
-
end
|
74
|
-
content += TavernaPlayer.output_renderer.render(data, type)
|
75
|
-
content += "</p></li>"
|
76
|
-
end
|
77
|
-
i += 1
|
78
|
-
end
|
79
|
-
|
80
|
-
raw(content += "</ol>")
|
81
|
-
end
|
82
|
-
|
83
24
|
end
|
84
25
|
end
|
@@ -40,8 +40,40 @@ module TavernaPlayer
|
|
40
40
|
# :method: value
|
41
41
|
# :call-seq:
|
42
42
|
# value -> string
|
43
|
+
# value(indices) -> string
|
43
44
|
#
|
44
|
-
# Return the value held in this port if there is one.
|
45
|
+
# Return the value held in this port if there is one. Pass in a list of
|
46
|
+
# indices if it is a list port.
|
47
|
+
#
|
48
|
+
# For a port of depth 0:
|
49
|
+
#
|
50
|
+
# value = output.value
|
51
|
+
#
|
52
|
+
# For a port of depth 2:
|
53
|
+
#
|
54
|
+
# value = output.value(0, 0)
|
55
|
+
# value = output.value([1, 2])
|
56
|
+
#
|
57
|
+
# Trying to get a list value out of a port of depth 0 will simply return
|
58
|
+
# the port's value.
|
59
|
+
|
60
|
+
##
|
61
|
+
# :method: path
|
62
|
+
# :call-seq:
|
63
|
+
# path -> string
|
64
|
+
# path(indices) -> string
|
65
|
+
#
|
66
|
+
# Return a url path segment that addresses this output value. Pass in a
|
67
|
+
# list of indices if it is a list port.
|
68
|
+
#
|
69
|
+
# For a port of depth 0 called "OUT":
|
70
|
+
#
|
71
|
+
# path = output.path # => "/runs/1/output/OUT"
|
72
|
+
#
|
73
|
+
# For a port of depth 2 called "OUT_LIST":
|
74
|
+
#
|
75
|
+
# path = output.path(0, 0) # => "runs/1/output/OUT_LIST/0/0"
|
76
|
+
# path = output.path([1, 2]) # => "runs/1/output/OUT_LIST/1/2"
|
45
77
|
|
46
78
|
##
|
47
79
|
# :method: metadata
|
@@ -26,7 +26,7 @@
|
|
26
26
|
<b>Value:</b>
|
27
27
|
<%= "(#{output.metadata[:type]})" if output.depth == 0 %>
|
28
28
|
<%= link_to "Download", run_path(run) + "/download/output/#{output.name}" %>
|
29
|
-
<%=
|
29
|
+
<%= TavernaPlayer.port_renderer.render(output) %>
|
30
30
|
</p>
|
31
31
|
|
32
32
|
<% end%>
|
@@ -111,9 +111,9 @@ There is also some manual setup to do, if you haven't already done it:
|
|
111
111
|
They will be saved to "lib/taverna_player_callbacks.rb". Don't forget to
|
112
112
|
then require and register them in the Taverna Player initializer.
|
113
113
|
|
114
|
-
11. You can add to, or change, the workflow
|
115
|
-
|
116
|
-
|
114
|
+
11. You can add to, or change, the workflow port render methods to better
|
115
|
+
suit your particular application. To copy the defaults that Taverna
|
116
|
+
Player ships with into your application for customization run:
|
117
117
|
|
118
118
|
rails generate taverna_player:renderers
|
119
119
|
|
@@ -16,41 +16,69 @@
|
|
16
16
|
# defaults automatically.
|
17
17
|
#
|
18
18
|
# Each method MUST accept two parameters:
|
19
|
-
# * The first (
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# * The second (type) is the MIME type of the output as a string. This allows
|
23
|
-
# a single method to handle multiple types or sub-types if needed.
|
19
|
+
# * The first (port) is the port to be rendered.
|
20
|
+
# * The second (index) is the index into the port. For singleton ports this
|
21
|
+
# will be the empty list.
|
24
22
|
#
|
25
23
|
# Note that you can use most of the ActiveView Helpers here as global methods
|
26
24
|
# but the image_tag() method does not work as explained below.
|
27
25
|
|
28
|
-
def format_text(
|
26
|
+
def format_text(port, index = [])
|
29
27
|
# Use CodeRay to format text so that newlines are respected.
|
30
|
-
content = CodeRay.scan(
|
28
|
+
content = CodeRay.scan(port.value(index), :text).div(:css => :class)
|
31
29
|
|
32
30
|
# Use auto_link to turn URI-like text into links.
|
33
31
|
auto_link(content, :html => { :target => '_blank' }, :sanitize => false)
|
34
32
|
end
|
35
33
|
|
36
|
-
def format_xml(
|
34
|
+
def format_xml(port, index = [])
|
37
35
|
# Make sure XML is indented consistently.
|
38
36
|
out = String.new
|
39
|
-
REXML::Document.new(
|
37
|
+
REXML::Document.new(port.value(index)).write(out, 1)
|
40
38
|
CodeRay.scan(out, :xml).div(:css => :class, :line_numbers => :table)
|
41
39
|
end
|
42
40
|
|
43
|
-
def show_image(
|
41
|
+
def show_image(port, index = [])
|
44
42
|
# Can't use image_tag() here because the image doesn't really exist (it's in
|
45
43
|
# a zip file, really) and this confuses the Rails asset pipeline.
|
46
|
-
tag("img", :src =>
|
44
|
+
tag("img", :src => port.path(index))
|
47
45
|
end
|
48
46
|
|
49
|
-
def workflow_error(
|
50
|
-
link_to("This output is a workflow error.",
|
47
|
+
def workflow_error(port, index = [])
|
48
|
+
link_to("This output is a workflow error.", port.path(index))
|
51
49
|
end
|
52
50
|
|
53
|
-
def cannot_inline(
|
51
|
+
def cannot_inline(port, index = [])
|
54
52
|
"Sorry but we cannot show this type of content in the browser. Please " +
|
55
|
-
link_to("download it",
|
53
|
+
link_to("download it", port.path(index)) + " to view it on " +
|
54
|
+
"your local machine."
|
55
|
+
end
|
56
|
+
|
57
|
+
# Rendering an empty port has no need of the index parameter.
|
58
|
+
def empty_port(port, _)
|
59
|
+
"<div><empty port></div>"
|
60
|
+
end
|
61
|
+
|
62
|
+
# Rendering a list port requires recursion. In this implementation an extra
|
63
|
+
# parameter (types) is added to drive the recursion; we can't just keep track
|
64
|
+
# of depth because we need to know the length of each sub-list - and types can
|
65
|
+
# be used to pass that through for us.
|
66
|
+
def list_port(port, index = [], types = nil)
|
67
|
+
types = port.metadata[:type] if types.nil?
|
68
|
+
|
69
|
+
content = "<ol>"
|
70
|
+
i = 0
|
71
|
+
types.each do |type|
|
72
|
+
if type.is_a?(Array)
|
73
|
+
content += "<li><br />" +
|
74
|
+
list_port(port, index + [i], type) + "</li>"
|
75
|
+
else
|
76
|
+
content += "<li>(#{type})<p>" +
|
77
|
+
TavernaPlayer.port_renderer.render(port, index + [i]) +
|
78
|
+
"</p></li>"
|
79
|
+
end
|
80
|
+
i += 1
|
81
|
+
end
|
82
|
+
|
83
|
+
content += "</ol>"
|
56
84
|
end
|
@@ -79,22 +79,22 @@ TavernaPlayer.setup do |config|
|
|
79
79
|
#config.run_failed_callback = "player_run_failed_callback"
|
80
80
|
#config.run_failed_callback = :player_run_failed_callback
|
81
81
|
|
82
|
-
# Callbacks to be run to render various types of workflow
|
83
|
-
#
|
82
|
+
# Callbacks to be run to render various types of workflow port. These can be
|
83
|
+
# defined as Proc objects or as methods and referenced by name.
|
84
84
|
#
|
85
85
|
# Be careful! If a callback fails then users will see an Internal Server
|
86
|
-
# Error (HTTP status code 500) instead of their run outputs!
|
86
|
+
# Error (HTTP status code 500) instead of their run inputs and/or outputs!
|
87
87
|
#
|
88
88
|
# Add callbacks in this initializer or define them elsewhere and require the
|
89
89
|
# file as usual (if they are not pulled in by some other code). You can
|
90
|
-
# create example
|
90
|
+
# create example callbacks using:
|
91
91
|
# "rails generate taverna_player:renderers"
|
92
92
|
# which will put them in "lib/taverna_player_renderers.rb".
|
93
93
|
#require "taverna_player_renderers"
|
94
94
|
|
95
|
-
# Renderers for each type of
|
95
|
+
# Renderers for each type of value (referenced by MIME type) must then be
|
96
96
|
# registered. All the renderers shown below are supplied as defaults.
|
97
|
-
#config.
|
97
|
+
#config.port_renderers do |renderers|
|
98
98
|
# Set a default renderer for if there is a workflow type that browsers
|
99
99
|
# can't otherwise handle.
|
100
100
|
#renderers.default(:cannot_inline)
|
@@ -104,7 +104,7 @@ TavernaPlayer.setup do |config|
|
|
104
104
|
# aren't otherwise registered.
|
105
105
|
#renderers.add("text/plain", :format_text, true)
|
106
106
|
|
107
|
-
# This renderer overrides the default text/* renderer for text/xml
|
107
|
+
# This renderer overrides the default text/* renderer for text/xml values.
|
108
108
|
#renderers.add("text/xml", :format_xml)
|
109
109
|
|
110
110
|
# Browsers can't show all image types so just register very common ones.
|
@@ -116,6 +116,10 @@ TavernaPlayer.setup do |config|
|
|
116
116
|
# This is the workflow error type and you should have a special renderer
|
117
117
|
# for it.
|
118
118
|
#renderers.add("application/x-error", :workflow_error)
|
119
|
+
|
120
|
+
# If your workflows have list outputs (probable) then something to render
|
121
|
+
# lists is also needed.
|
122
|
+
#renderers.list(:list_port)
|
119
123
|
#end
|
120
124
|
end
|
121
125
|
|
data/lib/taverna-player.rb
CHANGED
@@ -69,29 +69,30 @@ module TavernaPlayer
|
|
69
69
|
mattr_accessor :current_user_callback
|
70
70
|
@@current_user_callback = nil
|
71
71
|
|
72
|
-
# Setup default
|
73
|
-
mattr_reader :
|
74
|
-
@@
|
75
|
-
@@
|
76
|
-
@@
|
77
|
-
@@
|
78
|
-
@@
|
79
|
-
@@
|
80
|
-
@@
|
81
|
-
@@
|
82
|
-
@@
|
83
|
-
@@
|
84
|
-
@@
|
72
|
+
# Setup default port render callbacks.
|
73
|
+
mattr_reader :port_renderer
|
74
|
+
@@port_renderer = PortRenderer.new
|
75
|
+
@@port_renderer.default(:cannot_inline_tp_default)
|
76
|
+
@@port_renderer.list(:list_tp_default)
|
77
|
+
@@port_renderer.add("text/plain", :format_text_tp_default, true)
|
78
|
+
@@port_renderer.add("text/xml", :format_xml_tp_default)
|
79
|
+
@@port_renderer.add("image/jpeg", :show_image_tp_default)
|
80
|
+
@@port_renderer.add("image/png", :show_image_tp_default)
|
81
|
+
@@port_renderer.add("image/gif", :show_image_tp_default)
|
82
|
+
@@port_renderer.add("image/bmp", :show_image_tp_default)
|
83
|
+
@@port_renderer.add("application/x-error", :workflow_error_tp_default)
|
84
|
+
@@port_renderer.add("application/x-empty", :empty_tp_default)
|
85
|
+
@@port_renderer.add("inode/x-empty", :empty_tp_default)
|
85
86
|
|
86
87
|
# :call-seq:
|
87
|
-
#
|
88
|
+
# port_renderers {|renderer| ...}
|
88
89
|
#
|
89
90
|
# Set up the renderers for each MIME type that you want to be able to show
|
90
91
|
# in the browser. In most cases the supplied defaults will be sufficient.
|
91
92
|
#
|
92
93
|
# See the taverna_player initializer for more information.
|
93
|
-
def self.
|
94
|
-
yield @@
|
94
|
+
def self.port_renderers
|
95
|
+
yield @@port_renderer if block_given?
|
95
96
|
end
|
96
97
|
|
97
98
|
# Path to place where files should be stored.
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# Copyright (c) 2013 The University of Manchester, UK.
|
3
|
+
#
|
4
|
+
# BSD Licenced. See LICENCE.rdoc for details.
|
5
|
+
#
|
6
|
+
# Taverna Player was developed in the BioVeL project, funded by the European
|
7
|
+
# Commission 7th Framework Programme (FP7), through grant agreement
|
8
|
+
# number 283359.
|
9
|
+
#
|
10
|
+
# Author: Robert Haines
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
|
13
|
+
module TavernaPlayer
|
14
|
+
module Concerns
|
15
|
+
module Callback
|
16
|
+
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
def callback(cb, *params)
|
20
|
+
if cb.is_a? Proc
|
21
|
+
cb.call(*params)
|
22
|
+
else
|
23
|
+
method(cb).call(*params)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -17,6 +17,9 @@ module TavernaPlayer
|
|
17
17
|
|
18
18
|
extend ActiveSupport::Concern
|
19
19
|
|
20
|
+
include TavernaPlayer::Concerns::Callback
|
21
|
+
include TavernaPlayer::Concerns::Utils
|
22
|
+
|
20
23
|
included do
|
21
24
|
respond_to :html, :json, :js
|
22
25
|
|
@@ -55,7 +58,7 @@ module TavernaPlayer
|
|
55
58
|
return if params[:run][:embedded] == "true" || TavernaPlayer.user_proxy.nil?
|
56
59
|
|
57
60
|
unless TavernaPlayer.current_user_callback.blank?
|
58
|
-
user =
|
61
|
+
user = callback(TavernaPlayer.current_user_callback)
|
59
62
|
params[:run][:user_id] = user.id unless user.nil?
|
60
63
|
end
|
61
64
|
end
|
@@ -76,13 +79,6 @@ module TavernaPlayer
|
|
76
79
|
end
|
77
80
|
end
|
78
81
|
|
79
|
-
# This is here because of Taverna's infinitely deep output ports :-(
|
80
|
-
def recurse_into_lists(list, indexes)
|
81
|
-
return list if indexes.empty? || !list.is_a?(Array)
|
82
|
-
i = indexes.shift
|
83
|
-
return recurse_into_lists(list[i], indexes)
|
84
|
-
end
|
85
|
-
|
86
82
|
# Choose a layout for the page depending on action and embedded status.
|
87
83
|
def choose_layout
|
88
84
|
if (action_name == "new" || action_name == "show") && @run.embedded?
|
@@ -77,6 +77,17 @@ module TavernaPlayer
|
|
77
77
|
end
|
78
78
|
end
|
79
79
|
|
80
|
+
def deep_value(index)
|
81
|
+
path = index.map { |j| j += 1 }.join("/")
|
82
|
+
|
83
|
+
data = String.new
|
84
|
+
Zip::ZipFile.open(file.path) do |zip|
|
85
|
+
data = zip.read("#{path}")
|
86
|
+
end
|
87
|
+
|
88
|
+
data
|
89
|
+
end
|
90
|
+
|
80
91
|
end # included
|
81
92
|
|
82
93
|
def display_name
|
@@ -87,10 +98,20 @@ module TavernaPlayer
|
|
87
98
|
self[:value]
|
88
99
|
end
|
89
100
|
|
90
|
-
def value
|
91
|
-
|
101
|
+
def value(*indices)
|
102
|
+
if depth == 0
|
103
|
+
v = self[:value]
|
104
|
+
|
105
|
+
(!v.blank? && !file.path.blank?) ? File.read(file.path) : v
|
106
|
+
else
|
107
|
+
deep_value([*indices].flatten)
|
108
|
+
end
|
109
|
+
end
|
92
110
|
|
93
|
-
|
111
|
+
def path(*indices)
|
112
|
+
index = [*indices].flatten
|
113
|
+
path = index.empty? ? "" : "/" + index.join("/")
|
114
|
+
file_url_via_run + path
|
94
115
|
end
|
95
116
|
|
96
117
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#------------------------------------------------------------------------------
|
2
|
+
# Copyright (c) 2013 The University of Manchester, UK.
|
3
|
+
#
|
4
|
+
# BSD Licenced. See LICENCE.rdoc for details.
|
5
|
+
#
|
6
|
+
# Taverna Player was developed in the BioVeL project, funded by the European
|
7
|
+
# Commission 7th Framework Programme (FP7), through grant agreement
|
8
|
+
# number 283359.
|
9
|
+
#
|
10
|
+
# Author: Robert Haines
|
11
|
+
#------------------------------------------------------------------------------
|
12
|
+
|
13
|
+
module TavernaPlayer
|
14
|
+
module Concerns
|
15
|
+
module Utils
|
16
|
+
|
17
|
+
extend ActiveSupport::Concern
|
18
|
+
|
19
|
+
# Taverna can have arbitrary (therefore effectively "infinite") port
|
20
|
+
# depths so we need to recurse into them. This code is common across a
|
21
|
+
# number of other modules.
|
22
|
+
def recurse_into_lists(list, indexes)
|
23
|
+
return list if indexes.empty? || !list.is_a?(Array)
|
24
|
+
i = indexes.shift
|
25
|
+
recurse_into_lists(list[i], indexes)
|
26
|
+
end
|
27
|
+
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -12,14 +12,17 @@
|
|
12
12
|
|
13
13
|
module TavernaPlayer
|
14
14
|
|
15
|
-
# This class manages the rendering of many different
|
16
|
-
# be
|
15
|
+
# This class manages the rendering of many different port types that could
|
16
|
+
# be associated with a workflow. It can be configured with new types and the
|
17
17
|
# example renderers for each type can also be changed. An example of how to
|
18
18
|
# set it up can be found in the taverna_player initializer.
|
19
19
|
#
|
20
20
|
# Each renderer has all of the ActionView::Helpers (such as link_to, tag,
|
21
21
|
# etc) available to them.
|
22
|
-
class
|
22
|
+
class PortRenderer
|
23
|
+
include TavernaPlayer::Concerns::Callback
|
24
|
+
include TavernaPlayer::Concerns::Utils
|
25
|
+
|
23
26
|
# The renderers are all called in the scope of this class so we include
|
24
27
|
# ActionView::Helpers here so that they are all available to them.
|
25
28
|
include ActionView::Helpers
|
@@ -75,21 +78,30 @@ module TavernaPlayer
|
|
75
78
|
end
|
76
79
|
|
77
80
|
# :call-seq:
|
78
|
-
#
|
81
|
+
# list(method)
|
79
82
|
#
|
80
|
-
#
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
@hash[type.media_type][:default] || @hash[:default]
|
83
|
+
# Set a renderer to handle list ports. This will typically format the
|
84
|
+
# list somehow and render the list items with further calls to
|
85
|
+
# TavernaPlayer.port_renderer.render.
|
86
|
+
def list(method)
|
87
|
+
@hash[:list] = method
|
88
|
+
end
|
87
89
|
|
88
|
-
|
89
|
-
|
90
|
+
# :call-seq:
|
91
|
+
# render(port) -> markup
|
92
|
+
#
|
93
|
+
# This is the method that calls the correct renderer for the given port
|
94
|
+
# and returns the resultant rendering.
|
95
|
+
def render(port, index = [])
|
96
|
+
if port.depth > 0 && index.empty?
|
97
|
+
renderer = @hash[:list]
|
90
98
|
else
|
91
|
-
|
99
|
+
type = MIME::Types[recurse_into_lists(port.metadata[:type], index.dup)].first
|
100
|
+
renderer = @hash[type.media_type][type.sub_type] ||
|
101
|
+
@hash[type.media_type][:default] || @hash[:default]
|
92
102
|
end
|
103
|
+
|
104
|
+
raw(callback(renderer, port, index))
|
93
105
|
end
|
94
106
|
|
95
107
|
end
|
@@ -10,32 +10,53 @@
|
|
10
10
|
# Author: Robert Haines
|
11
11
|
#------------------------------------------------------------------------------
|
12
12
|
|
13
|
-
def format_text_tp_default(
|
14
|
-
content = CodeRay.scan(
|
13
|
+
def format_text_tp_default(port, index = [])
|
14
|
+
content = CodeRay.scan(port.value(index), :text).div(:css => :class)
|
15
15
|
auto_link(content, :html => { :target => '_blank' }, :sanitize => false)
|
16
16
|
end
|
17
17
|
|
18
|
-
def format_xml_tp_default(
|
18
|
+
def format_xml_tp_default(port, index = [])
|
19
19
|
out = String.new
|
20
|
-
REXML::Document.new(
|
20
|
+
REXML::Document.new(port.value(index)).write(out, 1)
|
21
21
|
CodeRay.scan(out, :xml).div(:css => :class, :line_numbers => :table)
|
22
22
|
end
|
23
23
|
|
24
|
-
def show_image_tp_default(
|
24
|
+
def show_image_tp_default(port, index = [])
|
25
25
|
# Can't use image_tag() here because the image doesn't really exist (it's in
|
26
26
|
# a zip file, really) and this confuses the Rails asset pipeline.
|
27
|
-
tag("img", :src =>
|
27
|
+
tag("img", :src => port.path(index))
|
28
28
|
end
|
29
29
|
|
30
|
-
def workflow_error_tp_default(
|
31
|
-
link_to("This output is a workflow error.",
|
30
|
+
def workflow_error_tp_default(port, index = [])
|
31
|
+
link_to("This output is a workflow error.", port.path(index))
|
32
32
|
end
|
33
33
|
|
34
|
-
def cannot_inline_tp_default(
|
34
|
+
def cannot_inline_tp_default(port, index = [])
|
35
35
|
"Sorry but we cannot show this type of content in the browser. Please " +
|
36
|
-
link_to("download it",
|
36
|
+
link_to("download it", port.path(index)) + " to view it on " +
|
37
|
+
"your local machine."
|
37
38
|
end
|
38
39
|
|
39
|
-
def empty_tp_default(
|
40
|
-
"<div><empty
|
40
|
+
def empty_tp_default(port, _)
|
41
|
+
"<div><empty port></div>"
|
42
|
+
end
|
43
|
+
|
44
|
+
def list_tp_default(port, index = [], types = nil)
|
45
|
+
types = port.metadata[:type] if types.nil?
|
46
|
+
|
47
|
+
content = "<ol>"
|
48
|
+
i = 0
|
49
|
+
types.each do |type|
|
50
|
+
if type.is_a?(Array)
|
51
|
+
content += "<li><br />" +
|
52
|
+
list_tp_default(port, index + [i], type) + "</li>"
|
53
|
+
else
|
54
|
+
content += "<li>(#{type})<p>" +
|
55
|
+
TavernaPlayer.port_renderer.render(port, index + [i]) +
|
56
|
+
"</p></li>"
|
57
|
+
end
|
58
|
+
i += 1
|
59
|
+
end
|
60
|
+
|
61
|
+
content += "</ol>"
|
41
62
|
end
|
@@ -12,6 +12,7 @@
|
|
12
12
|
|
13
13
|
module TavernaPlayer
|
14
14
|
class Worker
|
15
|
+
include TavernaPlayer::Concerns::Callback
|
15
16
|
|
16
17
|
# How to get the interaction presentation frame out of the interaction page.
|
17
18
|
INTERACTION_REGEX = /document\.getElementById\(\'presentationFrame\'\)\.src = \"(.+)\";/
|
@@ -29,7 +30,7 @@ module TavernaPlayer
|
|
29
30
|
def perform
|
30
31
|
unless TavernaPlayer.pre_run_callback.nil?
|
31
32
|
status_message "Running pre-run tasks"
|
32
|
-
|
33
|
+
callback(TavernaPlayer.pre_run_callback, @run)
|
33
34
|
end
|
34
35
|
|
35
36
|
status_message "Connecting to Taverna Server"
|
@@ -192,7 +193,7 @@ module TavernaPlayer
|
|
192
193
|
|
193
194
|
unless TavernaPlayer.run_failed_callback.nil?
|
194
195
|
status_message "Running post-failure tasks"
|
195
|
-
|
196
|
+
callback(TavernaPlayer.run_failed_callback, @run)
|
196
197
|
end
|
197
198
|
|
198
199
|
backtrace = exception.backtrace.join("\n")
|
@@ -206,7 +207,7 @@ module TavernaPlayer
|
|
206
207
|
|
207
208
|
unless TavernaPlayer.post_run_callback.nil?
|
208
209
|
status_message "Running post-run tasks"
|
209
|
-
|
210
|
+
callback(TavernaPlayer.post_run_callback, @run)
|
210
211
|
end
|
211
212
|
|
212
213
|
@run.state = :finished
|
@@ -215,14 +216,6 @@ module TavernaPlayer
|
|
215
216
|
|
216
217
|
private
|
217
218
|
|
218
|
-
def run_callback(callback, *params)
|
219
|
-
if callback.is_a? Proc
|
220
|
-
callback.call(*params)
|
221
|
-
else
|
222
|
-
method(callback).call(*params)
|
223
|
-
end
|
224
|
-
end
|
225
|
-
|
226
219
|
def download_log(run)
|
227
220
|
Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
|
228
221
|
tmp_file_name = File.join(tmp_dir, "log.txt")
|
@@ -313,7 +306,7 @@ module TavernaPlayer
|
|
313
306
|
|
314
307
|
unless TavernaPlayer.run_cancelled_callback.nil?
|
315
308
|
status_message "Running post-cancel tasks"
|
316
|
-
|
309
|
+
callback(TavernaPlayer.run_cancelled_callback, @run)
|
317
310
|
end
|
318
311
|
|
319
312
|
@run.state = :cancelled
|
File without changes
|
@@ -38,22 +38,27 @@ module TavernaPlayer
|
|
38
38
|
end
|
39
39
|
|
40
40
|
test "should route to a run output" do
|
41
|
-
assert_routing
|
41
|
+
assert_routing @run2.outputs[0].path,
|
42
42
|
{ :controller => "taverna_player/runs", :action => "output",
|
43
|
-
:id => "
|
43
|
+
:id => "2", :port => "OUT" }, {}, {}, "Did not route correctly"
|
44
44
|
end
|
45
45
|
|
46
46
|
test "should route to a deep run output" do
|
47
|
-
assert_routing
|
47
|
+
assert_routing @run2.outputs[0].path(0, 0),
|
48
48
|
{ :controller => "taverna_player/runs", :action => "output",
|
49
|
-
:id => "
|
49
|
+
:id => "2", :port => "OUT", :path => "0/0" }, {}, {},
|
50
|
+
"Did not route correctly"
|
51
|
+
|
52
|
+
assert_routing @run2.outputs[0].path([1, 2]),
|
53
|
+
{ :controller => "taverna_player/runs", :action => "output",
|
54
|
+
:id => "2", :port => "OUT", :path => "1/2" }, {}, {},
|
50
55
|
"Did not route correctly"
|
51
56
|
end
|
52
57
|
|
53
58
|
test "should route to a run input" do
|
54
|
-
assert_routing
|
59
|
+
assert_routing @run3.inputs[0].path,
|
55
60
|
{ :controller => "taverna_player/runs", :action => "input",
|
56
|
-
:id => "
|
61
|
+
:id => "3", :port => "IN_Value" }, {}, {}, "Did not route correctly"
|
57
62
|
end
|
58
63
|
|
59
64
|
test "should route to cancel on a run" do
|
@@ -14,32 +14,6 @@ require 'test_helper'
|
|
14
14
|
|
15
15
|
module TavernaPlayer
|
16
16
|
class RunsHelperTest < ActionView::TestCase
|
17
|
-
setup do
|
18
|
-
@run1 = taverna_player_runs(:one)
|
19
|
-
@port1 = taverna_player_run_ports(:one)
|
20
17
|
|
21
|
-
@run2 = taverna_player_runs(:three)
|
22
|
-
@port2 = taverna_player_run_ports(:four)
|
23
|
-
|
24
|
-
@run3 = taverna_player_runs(:four)
|
25
|
-
@port3 = taverna_player_run_ports(:five)
|
26
|
-
end
|
27
|
-
|
28
|
-
test "should show text outputs" do
|
29
|
-
assert_equal "Hello, World!", @port1.value, "Unexpected workflow output"
|
30
|
-
assert show_output(@run1, @port1).include?("<pre>Hello, World!</pre>"),
|
31
|
-
"Workflow output not formatted correctly"
|
32
|
-
|
33
|
-
assert_equal "Rob", @port2.value, "Unexpected workflow output"
|
34
|
-
assert show_output(@run2, @port2).include?("<pre>Rob</pre>"),
|
35
|
-
"Workflow output not formatted correctly"
|
36
|
-
end
|
37
|
-
|
38
|
-
test "should autolink text output" do
|
39
|
-
assert_equal "(http://example.com/path?query=1)", @port3.value,
|
40
|
-
"Unexpected workflow output"
|
41
|
-
assert show_output(@run3, @port3).include?("(<a href=\"http://example.com/path?query=1\" target=\"_blank\">http://example.com/path?query=1</a>)"),
|
42
|
-
"Workflow output not formatted correctly"
|
43
|
-
end
|
44
18
|
end
|
45
19
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: taverna-player
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-12-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rails
|
@@ -331,15 +331,17 @@ files:
|
|
331
331
|
- lib/tasks/delete-cancelled-runs.rake
|
332
332
|
- lib/tasks/delete-old-embedded-runs.rake
|
333
333
|
- lib/taverna-player.rb
|
334
|
+
- lib/taverna_player/concerns/callback.rb
|
334
335
|
- lib/taverna_player/concerns/controllers/runs_controller.rb
|
335
336
|
- lib/taverna_player/concerns/controllers/service_credentials_controller.rb
|
336
337
|
- lib/taverna_player/concerns/models/input_port.rb
|
337
338
|
- lib/taverna_player/concerns/models/output_port.rb
|
338
339
|
- lib/taverna_player/concerns/models/run.rb
|
339
340
|
- lib/taverna_player/concerns/models/run_port.rb
|
341
|
+
- lib/taverna_player/concerns/utils.rb
|
340
342
|
- lib/taverna_player/engine.rb
|
341
343
|
- lib/taverna_player/model_proxy.rb
|
342
|
-
- lib/taverna_player/
|
344
|
+
- lib/taverna_player/port_renderer.rb
|
343
345
|
- lib/taverna_player/render_callbacks.rb
|
344
346
|
- lib/taverna_player/version.rb
|
345
347
|
- lib/taverna_player/worker.rb
|
@@ -373,7 +375,7 @@ files:
|
|
373
375
|
- test/dummy/config/initializers/secret_token.rb
|
374
376
|
- test/dummy/config/initializers/session_store.rb
|
375
377
|
- test/dummy/config/initializers/taverna_player.rb
|
376
|
-
- test/dummy/config/initializers/taverna_server.example
|
378
|
+
- test/dummy/config/initializers/taverna_server.rb.example
|
377
379
|
- test/dummy/config/initializers/wrap_parameters.rb
|
378
380
|
- test/dummy/config/locales/en.yml
|
379
381
|
- test/dummy/config/routes.rb
|
@@ -454,7 +456,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
454
456
|
version: '0'
|
455
457
|
segments:
|
456
458
|
- 0
|
457
|
-
hash:
|
459
|
+
hash: 1554949292676939893
|
458
460
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
459
461
|
none: false
|
460
462
|
requirements:
|
@@ -463,7 +465,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
463
465
|
version: '0'
|
464
466
|
segments:
|
465
467
|
- 0
|
466
|
-
hash:
|
468
|
+
hash: 1554949292676939893
|
467
469
|
requirements: []
|
468
470
|
rubyforge_project:
|
469
471
|
rubygems_version: 1.8.21
|
@@ -498,7 +500,7 @@ test_files:
|
|
498
500
|
- test/dummy/config/initializers/secret_token.rb
|
499
501
|
- test/dummy/config/initializers/session_store.rb
|
500
502
|
- test/dummy/config/initializers/taverna_player.rb
|
501
|
-
- test/dummy/config/initializers/taverna_server.example
|
503
|
+
- test/dummy/config/initializers/taverna_server.rb.example
|
502
504
|
- test/dummy/config/initializers/wrap_parameters.rb
|
503
505
|
- test/dummy/config/locales/en.yml
|
504
506
|
- test/dummy/config/routes.rb
|