taverna-player 0.1.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/.gitignore +18 -0
- data/Gemfile +18 -0
- data/LICENCE.rdoc +29 -0
- data/README.rdoc +663 -0
- data/Rakefile +65 -0
- data/app/assets/javascripts/taverna_player/application.js +14 -0
- data/app/assets/javascripts/taverna_player/runs.js +42 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/assets/stylesheets/taverna_player/application.css +13 -0
- data/app/assets/stylesheets/taverna_player/coderay.css +120 -0
- data/app/controllers/taverna_player/application_controller.rb +16 -0
- data/app/controllers/taverna_player/runs_controller.rb +18 -0
- data/app/controllers/taverna_player/service_credentials_controller.rb +18 -0
- data/app/helpers/taverna_player/application_helper.rb +55 -0
- data/app/helpers/taverna_player/runs_helper.rb +84 -0
- data/app/models/taverna_player/interaction.rb +25 -0
- data/app/models/taverna_player/run.rb +117 -0
- data/app/models/taverna_player/run_port.rb +148 -0
- data/app/models/taverna_player/service_credential.rb +56 -0
- data/app/views/layouts/taverna_player/embedded.html.erb +27 -0
- data/app/views/taverna_player/runs/_button.html.erb +19 -0
- data/app/views/taverna_player/runs/_info.html.erb +56 -0
- data/app/views/taverna_player/runs/_info.json.jbuilder +2 -0
- data/app/views/taverna_player/runs/_inputs.html.erb +34 -0
- data/app/views/taverna_player/runs/_inputs.json.jbuilder +8 -0
- data/app/views/taverna_player/runs/_interaction.html.erb +68 -0
- data/app/views/taverna_player/runs/_outputs.html.erb +41 -0
- data/app/views/taverna_player/runs/_poll.html.erb +27 -0
- data/app/views/taverna_player/runs/create.json.jbuilder +3 -0
- data/app/views/taverna_player/runs/embedded/_button.html.erb +19 -0
- data/app/views/taverna_player/runs/embedded/_info.html.erb +25 -0
- data/app/views/taverna_player/runs/embedded/_inputs.html.erb +32 -0
- data/app/views/taverna_player/runs/embedded/_outputs.html.erb +32 -0
- data/app/views/taverna_player/runs/embedded/new.html.erb +58 -0
- data/app/views/taverna_player/runs/embedded/show.html.erb +39 -0
- data/app/views/taverna_player/runs/embedded/show.js.erb +35 -0
- data/app/views/taverna_player/runs/index.html.erb +40 -0
- data/app/views/taverna_player/runs/index.json.jbuilder +1 -0
- data/app/views/taverna_player/runs/new.html.erb +56 -0
- data/app/views/taverna_player/runs/new.json.jbuilder +1 -0
- data/app/views/taverna_player/runs/show.html.erb +29 -0
- data/app/views/taverna_player/runs/show.js.erb +25 -0
- data/app/views/taverna_player/runs/show.json.jbuilder +25 -0
- data/app/views/taverna_player/service_credentials/_form.html.erb +53 -0
- data/app/views/taverna_player/service_credentials/edit.html.erb +18 -0
- data/app/views/taverna_player/service_credentials/index.html.erb +41 -0
- data/app/views/taverna_player/service_credentials/new.html.erb +17 -0
- data/app/views/taverna_player/service_credentials/show.html.erb +36 -0
- data/config/routes.rb +34 -0
- data/db/migrate/20130313105546_create_taverna_player_runs.rb +16 -0
- data/db/migrate/20130315163019_create_taverna_player_run_ports.rb +15 -0
- data/db/migrate/20130318170744_add_attachment_file_to_taverna_player_run_ports.rb +6 -0
- data/db/migrate/20130319183634_create_delayed_jobs.rb +22 -0
- data/db/migrate/20130320102600_add_status_message_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130321100110_add_depth_and_metadata_to_taverna_player_run_ports.rb +6 -0
- data/db/migrate/20130704095504_add_attachment_results_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130705142704_add_embedded_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130714140911_create_taverna_player_interactions.rb +13 -0
- data/db/migrate/20130717083653_add_proxy_to_taverna_player_runs.rb +6 -0
- data/db/migrate/20130717155415_add_stop_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130811152840_add_attachment_log_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130811211725_change_taverna_player_runs_state_column.rb +5 -0
- data/db/migrate/20130812155839_add_name_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20130918135348_create_taverna_player_service_credentials.rb +15 -0
- data/db/migrate/20130919154200_add_displayed_to_taverna_player_interactions.rb +5 -0
- data/db/migrate/20131007153209_add_job_ref_to_taverna_player_runs.rb +13 -0
- data/db/migrate/20131010094537_add_reply_caching_to_taverna_player_interactions.rb +19 -0
- data/db/migrate/20131017141514_add_failure_message_to_taverna_player_run.rb +5 -0
- data/db/migrate/20131018152940_add_serial_number_to_taverna_player_interactions.rb +5 -0
- data/db/migrate/20131018160715_add_parent_run_id_to_taverna_player_runs.rb +5 -0
- data/db/migrate/20131102113933_add_page_uri_to_taverna_player_interaction.rb +5 -0
- data/db/migrate/20131105115218_remove_proxy_from_taverna_player_runs.rb +11 -0
- data/db/migrate/20131105141934_change_taverna_player_interactions_output_value_column_name.rb +5 -0
- data/db/migrate/20131112165520_add_user_to_taverna_player_run.rb +5 -0
- data/lib/generators/taverna_player/callbacks_generator.rb +25 -0
- data/lib/generators/taverna_player/controllers_generator.rb +30 -0
- data/lib/generators/taverna_player/install_generator.rb +30 -0
- data/lib/generators/taverna_player/job_generator.rb +26 -0
- data/lib/generators/taverna_player/models_generator.rb +27 -0
- data/lib/generators/taverna_player/renderers_generator.rb +26 -0
- data/lib/generators/taverna_player/views_generator.rb +27 -0
- data/lib/generators/templates/ReadMe.txt +118 -0
- data/lib/generators/templates/callbacks/render_callbacks.rb +56 -0
- data/lib/generators/templates/callbacks/worker_callbacks.rb +31 -0
- data/lib/generators/templates/controllers/runs_controller.rb +20 -0
- data/lib/generators/templates/controllers/service_credentials_controller.rb +20 -0
- data/lib/generators/templates/initializer.rb +154 -0
- data/lib/generators/templates/models/run.rb +20 -0
- data/lib/tasks/delete-cancelled-runs.rake +26 -0
- data/lib/tasks/delete-old-embedded-runs.rake +26 -0
- data/lib/taverna-player.rb +139 -0
- data/lib/taverna_player/concerns/controllers/runs_controller.rb +281 -0
- data/lib/taverna_player/concerns/controllers/service_credentials_controller.rb +89 -0
- data/lib/taverna_player/concerns/models/run.rb +205 -0
- data/lib/taverna_player/engine.rb +23 -0
- data/lib/taverna_player/model_proxy.rb +51 -0
- data/lib/taverna_player/output_renderer.rb +96 -0
- data/lib/taverna_player/render_callbacks.rb +41 -0
- data/lib/taverna_player/version.rb +15 -0
- data/lib/taverna_player/worker.rb +325 -0
- data/script/delayed_job +5 -0
- data/script/rails +8 -0
- data/taverna_player.gemspec +46 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/app/assets/javascripts/application.js +16 -0
- data/test/dummy/app/assets/stylesheets/application.css +14 -0
- data/test/dummy/app/controllers/application_controller.rb +15 -0
- data/test/dummy/app/controllers/home_controller.rb +16 -0
- data/test/dummy/app/controllers/taverna_player/runs_controller.rb +25 -0
- data/test/dummy/app/controllers/taverna_player/service_credentials_controller.rb +25 -0
- data/test/dummy/app/controllers/workflows_controller.rb +17 -0
- data/test/dummy/app/models/user.rb +15 -0
- data/test/dummy/app/models/workflow.rb +32 -0
- data/test/dummy/app/views/home/index.html.erb +18 -0
- data/test/dummy/app/views/layouts/application.html.erb +43 -0
- data/test/dummy/app/views/workflows/index.html.erb +35 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +58 -0
- data/test/dummy/config/boot.rb +10 -0
- data/test/dummy/config/database.yml +25 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +37 -0
- data/test/dummy/config/environments/production.rb +67 -0
- data/test/dummy/config/environments/test.rb +37 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +15 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/taverna_player.example.rb +40 -0
- data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/test/dummy/config/locales/en.yml +5 -0
- data/test/dummy/config/routes.rb +22 -0
- data/test/dummy/db/migrate/20130314103555_create_workflows.rb +12 -0
- data/test/dummy/db/migrate/20130318141557_create_taverna_player_runs.taverna_player.rb +17 -0
- data/test/dummy/db/migrate/20130318141558_create_taverna_player_run_ports.taverna_player.rb +16 -0
- data/test/dummy/db/migrate/20130318173013_add_attachment_file_to_taverna_player_run_ports.taverna_player.rb +7 -0
- data/test/dummy/db/migrate/20130319183816_create_delayed_jobs.taverna_player.rb +23 -0
- data/test/dummy/db/migrate/20130320102635_add_status_message_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130321161859_add_depth_and_metadata_to_taverna_player_run_ports.taverna_player.rb +7 -0
- data/test/dummy/db/migrate/20130704100146_add_attachment_results_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130705142816_add_embedded_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130714142144_create_taverna_player_interactions.taverna_player.rb +14 -0
- data/test/dummy/db/migrate/20130717084809_add_proxy_to_taverna_player_runs.taverna_player.rb +7 -0
- data/test/dummy/db/migrate/20130718102707_add_stop_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130811204449_add_attachment_log_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130811212709_change_taverna_player_runs_state_column.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130812161152_add_name_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20130918155525_create_taverna_player_service_credentials.taverna_player.rb +16 -0
- data/test/dummy/db/migrate/20130919155202_add_displayed_to_taverna_player_interactions.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131007153659_add_job_ref_to_taverna_player_runs.taverna_player.rb +14 -0
- data/test/dummy/db/migrate/20131016123941_add_reply_caching_to_taverna_player_interactions.taverna_player.rb +20 -0
- data/test/dummy/db/migrate/20131017141614_add_failure_message_to_taverna_player_run.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131018153316_add_serial_number_to_taverna_player_interactions.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131018164614_add_parent_run_id_to_taverna_player_runs.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131102114343_add_page_uri_to_taverna_player_interaction.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131105115724_remove_proxy_from_taverna_player_runs.taverna_player.rb +12 -0
- data/test/dummy/db/migrate/20131105142417_change_taverna_player_interactions_output_value_column_name.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131112165815_add_user_to_taverna_player_run.taverna_player.rb +6 -0
- data/test/dummy/db/migrate/20131114130937_create_users.rb +10 -0
- data/test/dummy/db/schema.rb +123 -0
- data/test/dummy/lib/callbacks.rb +35 -0
- data/test/dummy/log/.gitkeep +0 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +25 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/script/delayed_job +5 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/test/functional/home_controller_test.rb +28 -0
- data/test/dummy/test/functional/workflows_controller_test.rb +21 -0
- data/test/fixtures/files/crassostrea_gigas.csv +737 -0
- data/test/fixtures/taverna_player/interactions.yml +32 -0
- data/test/fixtures/taverna_player/run_ports.yml +54 -0
- data/test/fixtures/taverna_player/runs.yml +69 -0
- data/test/fixtures/taverna_player/service_credentials.yml +25 -0
- data/test/fixtures/users.yml +16 -0
- data/test/fixtures/workflows.yml +32 -0
- data/test/functional/taverna_player/runs_controller_test.rb +316 -0
- data/test/functional/taverna_player/service_credentials_controller_test.rb +99 -0
- data/test/taverna_player_test.rb +25 -0
- data/test/test_helper.rb +33 -0
- data/test/unit/helpers/taverna_player/application_helper_test.rb +70 -0
- data/test/unit/helpers/taverna_player/runs_helper_test.rb +45 -0
- data/test/unit/taverna_player/interaction_test.rb +47 -0
- data/test/unit/taverna_player/run_port_test.rb +309 -0
- data/test/unit/taverna_player/run_test.rb +196 -0
- data/test/unit/taverna_player/service_credential_test.rb +64 -0
- data/test/workflows/hello.t2flow +164 -0
- data/test/workflows/list_with_errors.t2flow +107 -0
- data/test/workflows/pass_through.t2flow +12 -0
- metadata +539 -0
|
@@ -0,0 +1,23 @@
|
|
|
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
|
+
class Engine < ::Rails::Engine
|
|
15
|
+
isolate_namespace TavernaPlayer
|
|
16
|
+
|
|
17
|
+
initializer "taverna_player.action_controller" do
|
|
18
|
+
ActiveSupport.on_load :action_controller do
|
|
19
|
+
helper TavernaPlayer::ApplicationHelper
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
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
|
+
class ModelProxy
|
|
15
|
+
attr_reader :class_name
|
|
16
|
+
|
|
17
|
+
def initialize(class_name, method_names = [])
|
|
18
|
+
if class_name.is_a?(String)
|
|
19
|
+
begin
|
|
20
|
+
@class_name = Object.const_get(class_name)
|
|
21
|
+
rescue NameError
|
|
22
|
+
@class_name = class_name.constantize
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
method_names.each do |name|
|
|
27
|
+
add_method(name.to_sym)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def add_method(name)
|
|
34
|
+
setter = "#{name}_method_name=".to_sym
|
|
35
|
+
mapper = name
|
|
36
|
+
|
|
37
|
+
(class << self; self; end).instance_eval do
|
|
38
|
+
# Define the method to use the mapped method on the object.
|
|
39
|
+
define_method name do |object|
|
|
40
|
+
mapper.nil? ? nil : object.send(mapper)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Define the method used to set the mapped method's name.
|
|
44
|
+
define_method setter do |method_name|
|
|
45
|
+
mapper = method_name.nil? ? nil : method_name.to_sym
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,96 @@
|
|
|
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
|
+
|
|
15
|
+
# This class manages the rendering of many different output types that could
|
|
16
|
+
# be produced by a workflow. It can be configured with new types and the
|
|
17
|
+
# example renderers for each type can also be changed. An example of how to
|
|
18
|
+
# set it up can be found in the taverna_player initializer.
|
|
19
|
+
#
|
|
20
|
+
# Each renderer has all of the ActionView::Helpers (such as link_to, tag,
|
|
21
|
+
# etc) available to them.
|
|
22
|
+
class OutputRenderer
|
|
23
|
+
# The renderers are all called in the scope of this class so we include
|
|
24
|
+
# ActionView::Helpers here so that they are all available to them.
|
|
25
|
+
include ActionView::Helpers
|
|
26
|
+
|
|
27
|
+
# :stopdoc:
|
|
28
|
+
# Taverna Workflow error MIME type
|
|
29
|
+
TAVERNA_ERROR_TYPE = MIME::Type.new("application/x-error")
|
|
30
|
+
|
|
31
|
+
# Empty file MIME types as used in older and new versions of "file".
|
|
32
|
+
EMPTY_FILE_OLD = MIME::Type.new("application/x-empty")
|
|
33
|
+
EMPTY_FILE_NEW = MIME::Type.new("inode/x-empty")
|
|
34
|
+
|
|
35
|
+
def initialize
|
|
36
|
+
@hash = Hash.new
|
|
37
|
+
MIME::Types.add(TAVERNA_ERROR_TYPE, EMPTY_FILE_OLD, EMPTY_FILE_NEW)
|
|
38
|
+
end
|
|
39
|
+
# :startdoc:
|
|
40
|
+
|
|
41
|
+
# :call-seq:
|
|
42
|
+
# add(mimetype, renderer, default = false)
|
|
43
|
+
#
|
|
44
|
+
# Add a renderer method for the specified MIME type. If you would like the
|
|
45
|
+
# renderer to be the default for that particular media type then pass true
|
|
46
|
+
# in the final parameter - the media type is the part of a MIME type before
|
|
47
|
+
# the slash (/), e.g. "text" or "image". The MIME type should be specified
|
|
48
|
+
# as a string.
|
|
49
|
+
def add(mimetype, method, default = false)
|
|
50
|
+
type = MIME::Types[mimetype].first
|
|
51
|
+
|
|
52
|
+
@hash[type.media_type] ||= {}
|
|
53
|
+
@hash[type.media_type][type.sub_type] = method
|
|
54
|
+
@hash[type.media_type][:default] = method if default
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# :call-seq:
|
|
58
|
+
# type_default(media_type, renderer)
|
|
59
|
+
#
|
|
60
|
+
# This is another way of setting the default renderer method for a whole
|
|
61
|
+
# media type (see the add method for more details).
|
|
62
|
+
def type_default(media_type, method)
|
|
63
|
+
@hash[media_type] ||= {}
|
|
64
|
+
@hash[media_type][:default] = method
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# :call-seq:
|
|
68
|
+
# default(method)
|
|
69
|
+
#
|
|
70
|
+
# Set a default renderer for any MIME type not specifically set. This
|
|
71
|
+
# could be used to supply a piece of text and a download link for any type
|
|
72
|
+
# that cannot normally be shown in the browser inline.
|
|
73
|
+
def default(method)
|
|
74
|
+
@hash[:default] = method
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# :call-seq:
|
|
78
|
+
# render(content, mimetype) -> markup
|
|
79
|
+
#
|
|
80
|
+
# This is the method that calls the correct renderer for the given content
|
|
81
|
+
# with the given MIME type and returns the resultant rendering.
|
|
82
|
+
def render(content, mimetype)
|
|
83
|
+
type = MIME::Types[mimetype].first
|
|
84
|
+
|
|
85
|
+
renderer = @hash[type.media_type][type.sub_type] ||
|
|
86
|
+
@hash[type.media_type][:default] || @hash[:default]
|
|
87
|
+
|
|
88
|
+
if renderer.is_a? Proc
|
|
89
|
+
renderer.call(content, type)
|
|
90
|
+
else
|
|
91
|
+
method(renderer).call(content, type)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
96
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
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
|
+
def format_text_tp_default(content, type)
|
|
14
|
+
content = CodeRay.scan(content, :text).div(:css => :class)
|
|
15
|
+
auto_link(content, :html => { :target => '_blank' }, :sanitize => false)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def format_xml_tp_default(content, type)
|
|
19
|
+
out = String.new
|
|
20
|
+
REXML::Document.new(content).write(out, 1)
|
|
21
|
+
CodeRay.scan(out, :xml).div(:css => :class, :line_numbers => :table)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def show_image_tp_default(content, type)
|
|
25
|
+
# Can't use image_tag() here because the image doesn't really exist (it's in
|
|
26
|
+
# a zip file, really) and this confuses the Rails asset pipeline.
|
|
27
|
+
tag("img", :src => content)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def workflow_error_tp_default(content, type)
|
|
31
|
+
link_to("This output is a workflow error.", content)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def cannot_inline_tp_default(content, type)
|
|
35
|
+
"Sorry but we cannot show this type of content in the browser. Please " +
|
|
36
|
+
link_to("download it", content) + " to view it on your local machine."
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def empty_tp_default(content, type)
|
|
40
|
+
"<div><empty output></div>"
|
|
41
|
+
end
|
|
@@ -0,0 +1,15 @@
|
|
|
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
|
+
VERSION = "0.1.0"
|
|
15
|
+
end
|
|
@@ -0,0 +1,325 @@
|
|
|
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
|
+
class Worker
|
|
15
|
+
|
|
16
|
+
# How to get the interaction presentation frame out of the interaction page.
|
|
17
|
+
INTERACTION_REGEX = /document\.getElementById\(\'presentationFrame\'\)\.src = \"(.+)\";/
|
|
18
|
+
|
|
19
|
+
def initialize(run)
|
|
20
|
+
@run = run
|
|
21
|
+
@workflow = TavernaPlayer.workflow_proxy.class_name.find(@run.workflow_id)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# This tells delayed_job to only try and complete each run once.
|
|
25
|
+
def max_attempts
|
|
26
|
+
1
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def perform
|
|
30
|
+
unless TavernaPlayer.pre_run_callback.nil?
|
|
31
|
+
status_message "Running pre-run tasks"
|
|
32
|
+
run_callback(TavernaPlayer.pre_run_callback, @run)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
status_message "Connecting to Taverna Server"
|
|
36
|
+
|
|
37
|
+
server_uri = URI.parse(TavernaPlayer.server_address)
|
|
38
|
+
credentials = T2Server::HttpBasic.new(TavernaPlayer.server_username,
|
|
39
|
+
TavernaPlayer.server_password)
|
|
40
|
+
conn_params = TavernaPlayer.server_connection
|
|
41
|
+
|
|
42
|
+
begin
|
|
43
|
+
server = T2Server::Server.new(server_uri, conn_params)
|
|
44
|
+
wkf = File.read(TavernaPlayer.workflow_proxy.file(@workflow))
|
|
45
|
+
|
|
46
|
+
# Try and create the run bearing in mind that the server might be at
|
|
47
|
+
# the limit of runs that it can hold at once.
|
|
48
|
+
begin
|
|
49
|
+
run = server.create_run(wkf, credentials)
|
|
50
|
+
rescue T2Server::ServerAtCapacityError
|
|
51
|
+
status_message "Server full - please wait; run will start soon"
|
|
52
|
+
|
|
53
|
+
if cancelled?
|
|
54
|
+
cancel
|
|
55
|
+
return
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
sleep(TavernaPlayer.server_retry_interval)
|
|
59
|
+
retry
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
status_message "Initializing new workflow run"
|
|
63
|
+
|
|
64
|
+
@run.run_id = run.id
|
|
65
|
+
@run.state = run.status
|
|
66
|
+
@run.create_time = run.create_time
|
|
67
|
+
@run.save
|
|
68
|
+
|
|
69
|
+
unless @run.inputs.size == 0
|
|
70
|
+
status_message "Uploading run inputs"
|
|
71
|
+
@run.inputs.each do |input|
|
|
72
|
+
unless input.file.blank?
|
|
73
|
+
run.input_port(input.name).file = input.file.path
|
|
74
|
+
else
|
|
75
|
+
run.input_port(input.name).value = input.value
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Just add in all service credentials right now
|
|
81
|
+
TavernaPlayer::ServiceCredential.all.each do |cred|
|
|
82
|
+
run.add_password_credential(cred.uri, cred.login, cred.password)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
status_message "Starting run"
|
|
86
|
+
run.name = @run.name
|
|
87
|
+
|
|
88
|
+
# Try and start the run bearing in mind that the server might be at
|
|
89
|
+
# the limit of runs that it can run at once.
|
|
90
|
+
while !run.start
|
|
91
|
+
status_message "Server busy - please wait; run will start soon"
|
|
92
|
+
|
|
93
|
+
if cancelled?
|
|
94
|
+
cancel(run)
|
|
95
|
+
return
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
sleep(TavernaPlayer.server_retry_interval)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
@run.state = run.status
|
|
102
|
+
@run.start_time = run.start_time
|
|
103
|
+
@run.save
|
|
104
|
+
|
|
105
|
+
status_message "Running"
|
|
106
|
+
until run.finished?
|
|
107
|
+
sleep(TavernaPlayer.server_poll_interval)
|
|
108
|
+
waiting = false
|
|
109
|
+
|
|
110
|
+
if cancelled?
|
|
111
|
+
cancel(run)
|
|
112
|
+
return
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
run.notifications(:requests).each do |note|
|
|
116
|
+
if @run.has_parent?
|
|
117
|
+
next if note.has_reply?
|
|
118
|
+
int = Interaction.find_by_run_id_and_serial(@run.parent_id, note.serial)
|
|
119
|
+
new_int = Interaction.find_or_initialize_by_run_id_and_unique_id_and_serial(@run.id, note.id, note.serial)
|
|
120
|
+
if new_int.new_record?
|
|
121
|
+
note.reply(int.feed_reply, int.data)
|
|
122
|
+
new_int.displayed = true
|
|
123
|
+
new_int.replied = true
|
|
124
|
+
new_int.feed_reply = int.feed_reply
|
|
125
|
+
new_int.data = int.data
|
|
126
|
+
new_int.save
|
|
127
|
+
end
|
|
128
|
+
else
|
|
129
|
+
waiting = true unless note.has_reply?
|
|
130
|
+
int = Interaction.find_or_initialize_by_run_id_and_unique_id_and_serial(@run.id, note.id, note.serial)
|
|
131
|
+
|
|
132
|
+
# Need to catch this here in case some other process has replied.
|
|
133
|
+
if note.has_reply? && !int.replied?
|
|
134
|
+
int.replied = true
|
|
135
|
+
int.save
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
unless int.replied?
|
|
139
|
+
if int.page.blank?
|
|
140
|
+
page = server.read(note.uri, "text/html", credentials)
|
|
141
|
+
|
|
142
|
+
INTERACTION_REGEX.match(page) do
|
|
143
|
+
page_uri = $1
|
|
144
|
+
|
|
145
|
+
if page_uri.starts_with?(server.uri.to_s)
|
|
146
|
+
page = server.read(URI.parse(page_uri), "text/html", credentials)
|
|
147
|
+
int.page = page.gsub("#{run.interactions_uri.to_s}/pmrpc.js",
|
|
148
|
+
"/assets/taverna_player/application.js")
|
|
149
|
+
else
|
|
150
|
+
int.page_uri = page_uri
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if int.data.blank?
|
|
156
|
+
int.data = note.input_data.force_encoding("UTF-8")
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
if !int.feed_reply.blank? && !int.data.blank?
|
|
160
|
+
note.reply(int.feed_reply, int.data)
|
|
161
|
+
|
|
162
|
+
int.replied = true
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
int.save
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
status_message(waiting ? "Waiting for user input" : "Running")
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
status_message "Gathering run outputs and log"
|
|
174
|
+
download_outputs(run)
|
|
175
|
+
download_log(run)
|
|
176
|
+
|
|
177
|
+
@run.outputs = process_outputs(run)
|
|
178
|
+
@run.finish_time = run.finish_time
|
|
179
|
+
@run.save
|
|
180
|
+
|
|
181
|
+
run.delete
|
|
182
|
+
rescue => exception
|
|
183
|
+
begin
|
|
184
|
+
unless run.nil?
|
|
185
|
+
download_log(run)
|
|
186
|
+
run.delete
|
|
187
|
+
end
|
|
188
|
+
rescue
|
|
189
|
+
# Try and grab the log then delete the run from Taverna Server here,
|
|
190
|
+
# but at this point we don't care if we fail...
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
unless TavernaPlayer.run_failed_callback.nil?
|
|
194
|
+
status_message "Running post-failure tasks"
|
|
195
|
+
run_callback(TavernaPlayer.run_failed_callback, @run)
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
backtrace = exception.backtrace.join("\n")
|
|
199
|
+
@run.failure_message = "#{exception.message}\n#{backtrace}"
|
|
200
|
+
|
|
201
|
+
@run.state = :failed
|
|
202
|
+
@run.finish_time = Time.now
|
|
203
|
+
status_message "Failed"
|
|
204
|
+
return
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
unless TavernaPlayer.post_run_callback.nil?
|
|
208
|
+
status_message "Running post-run tasks"
|
|
209
|
+
run_callback(TavernaPlayer.post_run_callback, @run)
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
@run.state = :finished
|
|
213
|
+
status_message "Finished"
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
private
|
|
217
|
+
|
|
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
|
+
def download_log(run)
|
|
227
|
+
Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
|
|
228
|
+
tmp_file_name = File.join(tmp_dir, "log.txt")
|
|
229
|
+
begin
|
|
230
|
+
run.log(tmp_file_name)
|
|
231
|
+
@run.log = File.new(tmp_file_name)
|
|
232
|
+
@run.save
|
|
233
|
+
rescue T2Server::AttributeNotFoundError
|
|
234
|
+
# We don't care if there's no log but we do want to catch the error!
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
def download_outputs(run)
|
|
240
|
+
Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
|
|
241
|
+
tmp_file_name = File.join(tmp_dir, "all.zip")
|
|
242
|
+
run.zip_output(tmp_file_name)
|
|
243
|
+
@run.results = File.new(tmp_file_name)
|
|
244
|
+
@run.save
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
def process_outputs(run)
|
|
249
|
+
outputs = []
|
|
250
|
+
|
|
251
|
+
Dir.mktmpdir(run.id, Rails.root.join("tmp")) do |tmp_dir|
|
|
252
|
+
run.output_ports.each_value do |port|
|
|
253
|
+
output = TavernaPlayer::RunPort::Output.new(:name => port.name,
|
|
254
|
+
:depth => port.depth)
|
|
255
|
+
|
|
256
|
+
tmp_file_name = File.join(tmp_dir, port.name)
|
|
257
|
+
|
|
258
|
+
if port.depth == 0
|
|
259
|
+
Zip::ZipFile.open(@run.results.path) do |zip|
|
|
260
|
+
if port.type =~ /text/
|
|
261
|
+
output.value = zip.read(port.name)
|
|
262
|
+
else
|
|
263
|
+
port_name = port.error? ? "#{port.name}.error" : port.name
|
|
264
|
+
output.file = singleton_output(port_name, tmp_file_name, zip)
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
else
|
|
268
|
+
# TODO: Need to rework this so it's not just re-downloading the
|
|
269
|
+
# whole port again. This is the quickest way right now though.
|
|
270
|
+
port.zip("#{tmp_file_name}.zip")
|
|
271
|
+
output.file = File.new("#{tmp_file_name}.zip")
|
|
272
|
+
end
|
|
273
|
+
|
|
274
|
+
output.metadata = {
|
|
275
|
+
:size => port.size,
|
|
276
|
+
:type => port.type
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
outputs << output
|
|
280
|
+
end
|
|
281
|
+
end
|
|
282
|
+
|
|
283
|
+
outputs
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def singleton_output(name, tmp_file, zip)
|
|
287
|
+
File.open(tmp_file, "wb") do |file|
|
|
288
|
+
file.write zip.read(name)
|
|
289
|
+
end
|
|
290
|
+
|
|
291
|
+
File.new(tmp_file)
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
def status_message(message)
|
|
295
|
+
@run.status_message = message
|
|
296
|
+
@run.save!
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def cancelled?
|
|
300
|
+
# Need to poll for updates as the run instance may have been
|
|
301
|
+
# changed in the Rails app.
|
|
302
|
+
@run.reload
|
|
303
|
+
@run.stop
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
def cancel(run = nil)
|
|
307
|
+
status_message "Cancelling"
|
|
308
|
+
|
|
309
|
+
unless run.nil?
|
|
310
|
+
download_log(run)
|
|
311
|
+
run.delete
|
|
312
|
+
end
|
|
313
|
+
|
|
314
|
+
unless TavernaPlayer.run_cancelled_callback.nil?
|
|
315
|
+
status_message "Running post-cancel tasks"
|
|
316
|
+
run_callback(TavernaPlayer.run_cancelled_callback, @run)
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
@run.state = :cancelled
|
|
320
|
+
@run.finish_time = Time.now
|
|
321
|
+
status_message "Cancelled"
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
end
|
|
325
|
+
end
|