taverna-player 0.2.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|