Diff
Modified: trunk/app/views/workflows/taverna2_beta/_internals.rhtml (2264 => 2265)
--- trunk/app/views/workflows/taverna2_beta/_internals.rhtml 2009-08-21 12:07:33 UTC (rev 2264)
+++ trunk/app/views/workflows/taverna2_beta/_internals.rhtml 2009-08-21 15:09:19 UTC (rev 2265)
@@ -1 +1,205 @@
-<p class="none_text">Not available</p>
\ No newline at end of file
+<% cache(:controller => 'workflows_cache', :action ="" 'internals', :id => workflow.id, :version => version) do -%>
+
+ <% if (model = workflow.get_workflow_model_object(version)) -%>
+
+ <!-- Sources -->
+ <% sources = model.sources -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Inputs (<%= sources.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless sources.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+
+ <% sources.each do |s| -%>
+ <tr>
+ <td><b><%= h s.name -%></b></td>
+ <td>
+ <% if s.descriptions %>
+ <% s.descriptions.each do |desc| %>
+ <%= h desc -%>
+ <%= "<hr />" unless desc==s.descriptions.last %>
+ <% end %>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <!-- Processors -->
+ <% processors = model.processors -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Processors (<%= processors.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless processors.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Name</th>
+ <th>Type</th>
+ <th>Description</th>
+ </tr>
+
+ <% processors.each do |p| -%>
+ <tr>
+ <td><b><%= h p.name -%></b></td>
+ <td><%= h p.type -%></td>
+ <td><%= h p.description -%></td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <!-- Beanshells -->
+ <% beanshells = model.beanshells -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Beanshells (<%= beanshells.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless beanshells.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Inputs</th>
+ <th>Outputs</th>
+ </tr>
+
+ <% beanshells.each do |b| -%>
+ <tr>
+ <td><b><%= h b.name -%></b></td>
+ <td><%= h b.description -%></td>
+ <td>
+ <% if b.inputs %>
+ <% b.inputs.each do |x| %>
+ <%=h x -%>
+ <%= "<hr />" unless x==b.inputs.last %>
+ <% end %>
+ <% end %>
+ </td>
+ <td>
+ <% if b.outputs %>
+ <% b.outputs.each do |x| %>
+ <%=h x -%>
+ <%= "<hr />" unless x==b.outputs.last %>
+ <% end %>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <!-- Sinks -->
+ <% sinks = model.sinks -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Outputs (<%= sinks.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless sinks.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ </tr>
+
+ <% sinks.each do |s| -%>
+ <tr>
+ <td><b><%= h s.name -%></b></td>
+ <td>
+ <% if s.descriptions %>
+ <% s.descriptions.each do |desc| %>
+ <%= h desc -%>
+ <%= "<hr />" unless desc==s.descriptions.last %>
+ <% end %>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <!-- Datalinks -->
+ <% datalinks = model.datalinks -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Datalinks (<%= datalinks.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless datalinks.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Sink</th>
+ <th>Source</th>
+ </tr>
+
+ <% datalinks.each do |dl| -%>
+ <tr>
+ <td><%= h dl.sink -%></td>
+ <td><%= h dl.source -%></td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <!-- Coordinations -->
+ <% coordinations = model.main.coordinations -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Coordinations (<%= coordinations.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless coordinations.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Controller</th>
+ <th>Target</th>
+ </tr>
+
+ <% coordinations.each do |c| -%>
+ <tr>
+ <td><%= h c.control -%></td>
+ <td><%= h c.target -%></td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <% else %>
+ <p class="none_text">Unavailable</p>
+ <% end -%>
+
+<% end %>
\ No newline at end of file
Modified: trunk/app/views/workflows/taverna2_beta/_run_options.rhtml (2264 => 2265)
--- trunk/app/views/workflows/taverna2_beta/_run_options.rhtml 2009-08-21 12:07:33 UTC (rev 2264)
+++ trunk/app/views/workflows/taverna2_beta/_run_options.rhtml 2009-08-21 15:09:19 UTC (rev 2265)
@@ -1 +1,34 @@
-<p class="none_text">Not available</p>
\ No newline at end of file
+<div style="margin: 0 0.5em;">
+ <h4>
+ Run this Workflow in the Taverna Workbench...
+ </h4>
+
+ <div class="option_box">
+
+ <p style="text-align: center;">
+ <b>Option 1:</b>
+ </p>
+
+ <p style="font-size: 93%; text-align: center;">
+ Copy and paste this link into File > 'Open workflow location...'<br/>
+ <%= link_to @download_url, @download_url %><br/>
+ <small>[ <%= link_to_function "More Info" + expand_image, visual_effect(:toggle_blind, "run_taverna_more_box", :duration => 0.3) -%> ]</small>
+ </p>
+
+ <div id="run_taverna_more_box" style="display: none;">
+ <p style="font-size: 85%; margin-top: 0.5em; text-align: center;">
+ Taverna is available from <%= link_to "http://taverna.sourceforge.net/", "http://taverna.sourceforge.net/", :popup => true %>
+ </p>
+
+ <p style="text-align: center; margin-top: 0.5em; font-size: 85%;">
+ If you are having problems downloading it in Taverna, you may need to provide your username and password in the URL so that Taverna can access the Workflow: <br/>
+ <% if logged_in? and current_user.username.nil? %>
+ First you need to <%= link_to 'register a username and password', edit_user_path(current_user) %> on your <%= Conf.sitename %> account.
+ <% else %>
+ <b>Replace <font color="#990000">http://</font> in the link above with <font color="#990000">http://<%=(logged_in? and !current_user.username.nil?) ? h(current_user.username) : "yourusername" %>:yourpassword@</font></b>
+ <% end %>
+ </p>
+ </div>
+
+ </div>
+</div>
Modified: trunk/app/views/workflows/taverna_scufl/_internals.rhtml (2264 => 2265)
--- trunk/app/views/workflows/taverna_scufl/_internals.rhtml 2009-08-21 12:07:33 UTC (rev 2264)
+++ trunk/app/views/workflows/taverna_scufl/_internals.rhtml 2009-08-21 15:09:19 UTC (rev 2265)
@@ -58,7 +58,52 @@
</div>
</div>
- <!-- Sinks -->
+ <!-- Beanshells -->
+ <% beanshells = model.beanshells -%>
+ <div class="fold">
+ <div class="foldTitle">
+ Beanshells (<%= beanshells.length -%>)
+ </div>
+ <div class="foldContent" style="display: none;">
+ <% unless beanshells.blank? -%>
+ <table class="simple">
+ <tr>
+ <th>Name</th>
+ <th>Description</th>
+ <th>Inputs</th>
+ <th>Outputs</th>
+ </tr>
+
+ <% beanshells.each do |b| -%>
+ <tr>
+ <td><b><%= h b.name -%></b></td>
+ <td><%= h b.description -%></td>
+ <td>
+ <% if b.inputs %>
+ <% b.inputs.each do |x| %>
+ <%=h x -%>
+ <%= "<hr />" unless x==b.inputs.last %>
+ <% end %>
+ <% end %>
+ </td>
+ <td>
+ <% if b.outputs %>
+ <% b.outputs.each do |x| %>
+ <%=h x -%>
+ <%= "<hr />" unless x==b.outputs.last %>
+ <% end %>
+ <% end %>
+ </td>
+ </tr>
+ <% end %>
+ </table>
+ <% else %>
+ <p class="none_text">None</p>
+ <% end %>
+ </div>
+ </div>
+
+ <!-- Sinks -->
<% sinks = model.sinks -%>
<div class="fold">
<div class="foldTitle">
Modified: trunk/lib/workflow_processors/taverna2_beta.rb (2264 => 2265)
--- trunk/lib/workflow_processors/taverna2_beta.rb 2009-08-21 12:07:33 UTC (rev 2264)
+++ trunk/lib/workflow_processors/taverna2_beta.rb 2009-08-21 15:09:19 UTC (rev 2265)
@@ -4,8 +4,18 @@
# See license.txt for details.
module WorkflowProcessors
+
+ require 't2flow/model'
+ require 't2flow/parser'
+ require 't2flow/dot'
+ require 'libxml'
+
+ require 'file_upload'
+
class Taverna2Beta < Interface
-
+ # Register Taverna 2 MIME Types
+ Mime::Type.register "application/vnd.taverna.t2flow+xml", :t2flow
+
# Begin Class Methods
# These:
@@ -29,23 +39,29 @@
end
def self.can_determine_type_from_file?
- false
+ true
end
def self.recognised?(file)
- false
+ begin
+ t2flow_model = T2Flow::Parser.new.parse(file.read)
+ file.rewind
+ return !t2flow_model.nil?
+ rescue
+ return false
+ end
end
def self.can_infer_metadata?
- false
+ true
end
def self.can_generate_preview_image?
- false
+ true
end
def self.can_generate_preview_svg?
- false
+ true
end
# End Class Methods
@@ -55,6 +71,7 @@
def initialize(workflow_definition)
super(workflow_definition)
+ @t2flow_model = T2Flow::Parser.new.parse(workflow_definition)
end
# End Object Initializer
@@ -64,8 +81,201 @@
# These provide more specific functionality for a given workflow definition, such as parsing for metadata and image generation.
+ # *** NEW ***
+ def get_name
+ return nil if @t2flow_model.nil?
+ if @t2flow_model.annotations.name.empty? || @t2flow_model.annotations.name=~/^(workflow|dataflow)\d*$/i
+ if @t2flow_model.annotations.titles.nil? || @t2flow_model.annotations.titles.empty?
+ return "[untitled]"
+ else
+ @t2flow_model.annotations.titles[0]
+ end
+ else
+ @t2flow_model.annotations.name
+ end
+ end
+ def get_title
+ titles = self.get_titles
+ if titles
+ return titles[0]
+ else
+ return self.get_name
+ end
+ end
+ # *** NEW ***
+ def get_titles
+ return nil if @t2flow_model.nil?
+ return @t2flow_model.annotations.titles
+ end
+
+ def get_description
+ descriptions = self.get_descriptions
+ if descriptions
+ desc = ""
+ descriptions.each { |x|
+ desc << x
+ desc << "<hr/>" unless x==descriptions.last
+ }
+ return desc
+ else
+ return nil
+ end
+ end
+
+ # *** NEW ***
+ def get_descriptions
+ return nil if @t2flow_model.nil?
+ return @t2flow_model.annotations.descriptions
+ end
+
+ # *** NEW ***
+ def get_authors
+ return nil if @t2flow_model.nil?
+ return @t2flow_model.annotations.authors
+ end
+
+ def get_preview_image
+ return nil if @t2flow_model.nil? || RUBY_PLATFORM =~ /mswin32/
+
+ title = self.get_name
+ filename = title.gsub(/[^\w\.\-]/,'_').downcase
+
+ i = Tempfile.new("image")
+ T2Flow::Dot.new.write_dot(i, @t2flow_model)
+ i.close(false)
+
+ img = StringIO.new(`dot -Tpng #{i.path}`)
+ img.extend FileUpload
+ img.original_filename = "#{filename}.png"
+ img.content_type = "image/png"
+
+ img
+ end
+
+ def get_preview_svg
+ return nil if @t2flow_model.nil? || RUBY_PLATFORM =~ /mswin32/
+
+ title = self.get_name
+ filename = title.gsub(/[^\w\.\-]/,'_').downcase
+
+ i = Tempfile.new("image")
+ T2Flow::Dot.new.write_dot(i, @t2flow_model)
+ i.close(false)
+
+ svg = StringIO.new(`dot -Tsvg #{i.path}`)
+ svg.extend FileUpload
+ svg.original_filename = "#{filename}.svg"
+ svg.content_type = "image/svg+xml"
+
+ svg
+ end
+
+ def get_workflow_model_object
+ @t2flow_model
+ end
+
+ def get_workflow_model_input_ports
+ return (@t2flow_model.nil? ? nil : @t2flow_model.sources)
+ end
+
+ def get_search_terms
+ def get_scufl_metadata(model)
+ words = StringIO.new
+
+ model.sources.each do |source|
+ words << " #{source.name}" if source.name
+ end
+
+ model.sinks.each do |sink|
+ words << " #{sink.name}" if sink.name
+ end
+
+ model.processors.each do |processor|
+ words << " #{processor.name}" if processor.name
+ words << " #{processor.description}" if processor.description
+ end
+
+ words.rewind
+ words.read
+ end
+
+ return "" if @t2flow_model.nil?
+ return get_scufl_metadata(@t2flow_model)
+ end
+
+ def get_components
+ model = @t2flow_model
+
+ components = LibXML::XML::Node.new('components')
+
+ sources = LibXML::XML::Node.new('sources')
+ sinks = LibXML::XML::Node.new('sinks')
+ processors = LibXML::XML::Node.new('processors')
+ datalinks = LibXML::XML::Node.new('datalinks')
+
+ model.sources.each do |source|
+ el = LibXML::XML::Node.new('source')
+ el << (LibXML::XML::Node.new('name') << source.name) if source.name
+ source.descriptions.each { |desc|
+ el << (XML::Node.new('description') << desc)
+ } if source.descriptions
+ source.example_values.each { |ex|
+ el << (XML::Node.new('example') << ex)
+ } if source.example_values
+ sources << el
+ end
+
+ model.sinks.each do |sink|
+ el = LibXML::XML::Node.new('sink')
+ el << (LibXML::XML::Node.new('name') << sink.name) if sink.name
+ sink.descriptions.each { |desc|
+ el << (XML::Node.new('description') << desc)
+ } if sink.descriptions
+ sink.example_values.each { |ex|
+ el << (XML::Node.new('example') << ex)
+ } if sink.example_values
+ sinks << el
+ end
+
+ model.processors.each do |processor|
+ el = LibXML::XML::Node.new('processor')
+ el << (LibXML::XML::Node.new('name') << processor.name) if processor.name
+ el << (LibXML::XML::Node.new('description') << processor.description) if processor.description
+ el << (LibXML::XML::Node.new('type') << processor.type) if processor.type
+ processors << el
+ end
+
+ model.datalinks.each do |datalink|
+ el = LibXML::XML::Node.new('datalink')
+
+ sink_bits = datalink.sink.split(':')
+ source_bits = datalink.source.split(':')
+
+ sink = LibXML::XML::Node.new('sink')
+ source = LibXML::XML::Node.new('source')
+
+ sink << (LibXML::XML::Node.new('node') << sink_bits[0]) if sink_bits[0]
+ sink << (LibXML::XML::Node.new('port') << sink_bits[1]) if sink_bits[1]
+
+ source << (LibXML::XML::Node.new('node') << source_bits[0]) if source_bits[0]
+ source << (LibXML::XML::Node.new('port') << source_bits[1]) if source_bits[1]
+
+ el << sink
+ el << source
+
+ datalinks << el
+ end
+
+ components << sources
+ components << sinks
+ components << processors
+ components << datalinks
+
+ components
+ end
+
# End Instance Methods
end
end