[ARVADOS] updated: e5d1f2f918be2c6a59ac4085276342cc4533fe2a

git at public.curoverse.com git at public.curoverse.com
Tue Feb 4 15:49:25 EST 2014


Summary of changes:
 .../app/controllers/collections_controller.rb      |    3 +-
 .../controllers/pipeline_instances_controller.rb   |   34 ++++++++---
 apps/workbench/app/helpers/provenance_helper.rb    |   20 +++++-
 apps/workbench/app/models/collection.rb            |    4 +
 .../app/views/application/_svg_div.html.erb        |   25 +++++----
 .../workbench/app/views/application/index.html.erb |    2 +-
 apps/workbench/app/views/application/show.html.erb |    2 +-
 .../collections/_show_provenance_graph.html.erb    |    7 +-
 .../app/views/collections/_show_used_by.html.erb   |   11 ++++
 .../app/views/pipeline_instances/compare.html.erb  |   12 ++++
 .../api/app/controllers/application_controller.rb  |   10 +++-
 .../arvados/v1/collections_controller.rb           |   59 ++++++++++++++++++++
 services/api/config/routes.rb                      |    1 +
 13 files changed, 157 insertions(+), 33 deletions(-)
 create mode 100644 apps/workbench/app/views/collections/_show_used_by.html.erb

       via  e5d1f2f918be2c6a59ac4085276342cc4533fe2a (commit)
       via  0c0bdf1c00e1f0a50bc5977f171ae1ac720c79bb (commit)
       via  9e3bb9b984ff700fc3455f87437a8f1ac5841f0e (commit)
       via  b2a75b1d0eab457047564a6901016c27a08fa36d (commit)
      from  345960e59c01e6f2071ee65a44fbc62288b278dc (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.


commit e5d1f2f918be2c6a59ac4085276342cc4533fe2a
Merge: 0c0bdf1 345960e
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Tue Feb 4 15:50:12 2014 -0500

    Merge branch '1977-provenance-report' of git.clinicalfuture.com:arvados into 1977-provenance-report
    
    # Please enter a commit message to explain why this merge is necessary,
    # especially if it merges an updated upstream into a topic branch.
    #
    # Lines starting with '#' will be ignored, and an empty message aborts
    # the commit.


commit 0c0bdf1c00e1f0a50bc5977f171ae1ac720c79bb
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Tue Feb 4 15:48:46 2014 -0500

    * Added used_by query for collections
    * Fixed svg div javascript/layouts after Tom's changes
    * Added hover css effect for graph lines
    * Added graph to pipeline instance comparison page

diff --git a/apps/workbench/app/controllers/collections_controller.rb b/apps/workbench/app/controllers/collections_controller.rb
index 7feba20..c6a7eaf 100644
--- a/apps/workbench/app/controllers/collections_controller.rb
+++ b/apps/workbench/app/controllers/collections_controller.rb
@@ -3,7 +3,7 @@ class CollectionsController < ApplicationController
   skip_before_filter :check_user_agreements, :only => [:show_file]
 
   def show_pane_list
-    %w(files attributes provenance provenance_graph)
+    %w(files attributes provenance provenance_graph used_by)
   end
   def index
     if params[:search].andand.length.andand > 0
@@ -103,6 +103,7 @@ class CollectionsController < ApplicationController
     
     Collection.where(uuid: @object.uuid).each do |u|
       @prov_svg = ProvenanceHelper::create_provenance_graph u.provenance, "provenance_svg", {:direction => :bottom_up, :combine_jobs => :script_only}
+      @used_by_svg = ProvenanceHelper::create_provenance_graph u.used_by, "used_by_svg", {:direction => :top_down, :combine_jobs => :script_only, :pdata_only => true}
     end
   end
 
diff --git a/apps/workbench/app/controllers/pipeline_instances_controller.rb b/apps/workbench/app/controllers/pipeline_instances_controller.rb
index a42a734..98ae0e6 100644
--- a/apps/workbench/app/controllers/pipeline_instances_controller.rb
+++ b/apps/workbench/app/controllers/pipeline_instances_controller.rb
@@ -3,21 +3,13 @@ class PipelineInstancesController < ApplicationController
   before_filter :find_objects_by_uuid, only: :compare
   include PipelineInstancesHelper
 
-  def show
-    @pipelines = [@object]
-
-    if params[:compare]
-      PipelineInstance.where(uuid: params[:compare]).each do |p|
-        @pipelines << p
-      end
-    end
-
+  def graph(pipelines)
     count = {}    
     provenance = {}
     pips = {}
     n = 1
 
-    @pipelines.each do |p|
+    pipelines.each do |p|
       collections = []
 
       p.components.each do |k, v|
@@ -49,6 +41,20 @@ class PipelineInstancesController < ApplicationController
       n = n << 1
     end
 
+    return provenance, pips
+  end
+
+  def show
+    @pipelines = [@object]
+
+    if params[:compare]
+      PipelineInstance.where(uuid: params[:compare]).each do |p|
+        @pipelines << p
+      end
+    end
+
+    provenance, pips = graph(@pipelines)
+
     @prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
       :all_script_parameters => true, 
       :combine_jobs => :script_and_version,
@@ -112,6 +118,14 @@ class PipelineInstancesController < ApplicationController
         end
       end
     end
+
+    provenance, pips = graph(@objects)
+
+    @prov_svg = ProvenanceHelper::create_provenance_graph provenance, "provenance_svg", {
+      :all_script_parameters => true, 
+      :combine_jobs => :script_and_version,
+      :script_version_nodes => true,
+      :pips => pips }
   end
 
   protected
diff --git a/apps/workbench/app/helpers/provenance_helper.rb b/apps/workbench/app/helpers/provenance_helper.rb
index 73b4a47..ef165e8 100644
--- a/apps/workbench/app/helpers/provenance_helper.rb
+++ b/apps/workbench/app/helpers/provenance_helper.rb
@@ -46,6 +46,12 @@ module ProvenanceHelper
       
         #"\"#{uuid}\" [label=\"#{rsc}\\n#{uuid}\",href=\"#{href}\"];\n"
         if rsc == Collection
+          puts uuid
+          if uuid == :"d41d8cd98f00b204e9800998ecf8427e+0"
+            # special case
+            puts "empty!"
+            return "\"#{uuid}\" [label=\"(empty collection)\"];\n"
+          end
           if @pdata[uuid] 
             #puts @pdata[uuid]
             if @pdata[uuid][:name]
@@ -128,7 +134,7 @@ module ProvenanceHelper
           sp.each do |v|
             if GenerateGraph::collection_uuid(v)
               gr += script_param_edges(job, "#{prefix}[#{i}]", v)
-            else
+            elsif @opts[:all_script_parameters]
               node += "', '" unless node == ""
               node = "['" if node == ""
               node += "#{v}"
@@ -144,7 +150,8 @@ module ProvenanceHelper
           end
         else
           m = GenerateGraph::collection_uuid(sp)
-          if m
+          #puts "#{m} pdata is #{@pdata[m.intern]}"
+          if m and (@pdata[m.intern] or (not @opts[:pdata_only]))
             gr += edge(job_uuid(job), m, {:label => prefix})
             gr += generate_provenance_edges(m)
           elsif @opts[:all_script_parameters]
@@ -182,6 +189,11 @@ module ProvenanceHelper
         # uuid is a collection
         gr += describe_node(uuid)
 
+        if m == :"d41d8cd98f00b204e9800998ecf8427e+0"
+          # empty collection, don't follow any further
+          return gr
+        end
+
         @pdata.each do |k, job|
           if job[:output] == uuid.to_s
             gr += edge(uuid, job_uuid(job), {:label => "output"})
@@ -265,8 +277,8 @@ module ProvenanceHelper
     end
     
     gr = """strict digraph {
-node [fontsize=8,shape=box];
-edge [fontsize=8];
+node [fontsize=10,shape=box];
+edge [fontsize=10];
 """
 
     if opts[:direction] == :bottom_up
diff --git a/apps/workbench/app/models/collection.rb b/apps/workbench/app/models/collection.rb
index cdd148c..bda5523 100644
--- a/apps/workbench/app/models/collection.rb
+++ b/apps/workbench/app/models/collection.rb
@@ -20,4 +20,8 @@ class Collection < ArvadosBase
   def provenance
     $arvados_api_client.api "collections/#{self.uuid}/", "provenance"
   end
+
+  def used_by
+    $arvados_api_client.api "collections/#{self.uuid}/", "used_by"
+  end
 end
diff --git a/apps/workbench/app/views/application/_svg_div.html.erb b/apps/workbench/app/views/application/_svg_div.html.erb
index f3f6a71..1e7fdf7 100644
--- a/apps/workbench/app/views/application/_svg_div.html.erb
+++ b/apps/workbench/app/views/application/_svg_div.html.erb
@@ -1,4 +1,5 @@
 <%= content_for :css do %>
+/* Need separate style for each instance of svg div because javascript will manipulate the properties. */
 #<%= divId %> {
  padding-left: 3px;
  overflow: auto;
@@ -7,27 +8,29 @@
  border-color: gray;
  position: absolute;
  left: 1px;
-
+}
+path:hover {
+stroke-width: 5;
 }
 <% end %>
 
-<div id="_<%= divId %>_container" style="padding-top: 41px; margin-top: -41px">
-  <script>
-    (function() {
+<%= content_for :js do %>
+    $(window).on('load', function() {
       var fn = function () { graph_zoom("<%= divId %>", "<%=svgId %>", 1) };
-      $(window).resize(fn);
-      $(window).load(fn);
-      $(window).scroll(fn);
-    })();
-  </script>
+      $(window).on('resize', fn);
+      $(window).on('scroll', fn);
+    });
+<% end %>
+
+<div id="_<%= divId %>_container" style="padding-top: 41px; margin-top: -41px">
   <div style="text-align: right">
     <a style="cursor: pointer"><span class="icon-zoom-out" onclick="graph_zoom('<%= divId %>', '<%= svgId %>', .9)"></span></a>
     <a style="cursor: pointer"><span class="icon-zoom-in" onclick="graph_zoom('<%= divId %>', '<%= svgId %>', 1./.9)"></span></a>
   </div>
 
   <div id="<%= divId %>">
-    <span id="_<%= divId %>_center" style="padding-left: 300px"/>
+    <span id="_<%= divId %>_center" style="padding-left: 300px"></span>
     <%= raw(svg) %>
   </div>
-  <div id="_<%= divId %>_padding" style="padding-bottom: 1em" />
+  <div id="_<%= divId %>_padding" style="padding-bottom: 1em"></div>
 </div>
diff --git a/apps/workbench/app/views/application/index.html.erb b/apps/workbench/app/views/application/index.html.erb
index 95e0b41..167fea1 100644
--- a/apps/workbench/app/views/application/index.html.erb
+++ b/apps/workbench/app/views/application/index.html.erb
@@ -17,7 +17,7 @@
 <div class="tabbable">
 <ul class="nav nav-tabs">
   <% pane_list.each_with_index do |pane, i| %>
-  <li class="<%= 'active' if i==0 %>"><a href="#<%= pane %>" data-toggle="tab"><%= pane.capitalize %></a></li>
+  <li class="<%= 'active' if i==0 %>"><a href="#<%= pane %>" data-toggle="tab" id="<%= pane %>-tab"> <%= pane.capitalize %></a></li>
   <% end %>
 </ul>
 
diff --git a/apps/workbench/app/views/application/show.html.erb b/apps/workbench/app/views/application/show.html.erb
index 348d9d9..d2abd72 100644
--- a/apps/workbench/app/views/application/show.html.erb
+++ b/apps/workbench/app/views/application/show.html.erb
@@ -26,7 +26,7 @@
 <div class="tabbable">
 <ul class="nav nav-tabs">
   <% pane_list.each_with_index do |pane, i| %>
-  <li class="<%= 'active' if i==0 %>"><a href="#<%= pane %>" data-toggle="tab"><%= pane.capitalize.gsub '_', ' ' %></a></li>
+  <li class="<%= 'active' if i==0 %>"><a href="#<%= pane %>" data-toggle="tab" id="<%= pane %>-tab"><%= pane.capitalize.gsub '_', ' ' %></a></li>
   <% end %>
 </ul>
 
diff --git a/apps/workbench/app/views/collections/_show_provenance_graph.html.erb b/apps/workbench/app/views/collections/_show_provenance_graph.html.erb
index 1f367c7..d127f4f 100644
--- a/apps/workbench/app/views/collections/_show_provenance_graph.html.erb
+++ b/apps/workbench/app/views/collections/_show_provenance_graph.html.erb
@@ -1,9 +1,10 @@
 <% content_for :js do %>
+  $(window).on('load',
     $(function() {
-      $('#prov-tab').on('shown', function() { provenance_sizing_fixup("provenance_graph", "provenance_svg"); });
-    })
+      $('#provenance_graph-tab').on('shown', function() { graph_zoom("provenance_graph_div", "provenance_svg", 1); });
+    }))
 <% end %>
 <%= render partial: 'application/svg_div', locals: {
-    divId: "provenance_graph", 
+    divId: "provenance_graph_div", 
     svgId: "provenance_svg", 
     svg: @prov_svg } %>
diff --git a/apps/workbench/app/views/collections/_show_used_by.html.erb b/apps/workbench/app/views/collections/_show_used_by.html.erb
new file mode 100644
index 0000000..837f30f
--- /dev/null
+++ b/apps/workbench/app/views/collections/_show_used_by.html.erb
@@ -0,0 +1,11 @@
+ <% content_for :js do %>
+  $(window).on('load',
+    $(function() {
+      $('#used_by-tab').on('shown', function() { graph_zoom("used_by_graph", "used_by_svg", 1); });
+    }))
+<% end %>
+<%= render partial: 'application/svg_div', locals: {
+    divId: "used_by_graph", 
+    svgId: "used_by_svg", 
+    svg: @used_by_svg } %>
+
diff --git a/apps/workbench/app/views/collections/show.html.erb b/apps/workbench/app/views/collections/show.html.erb
deleted file mode 100644
index f1943c3..0000000
--- a/apps/workbench/app/views/collections/show.html.erb
+++ /dev/null
@@ -1,263 +0,0 @@
-<%= content_for :css do %>
-<%# https://github.com/mbostock/d3/wiki/Ordinal-Scales %>
-<% n=-1; %w(#1f77b4 #ff7f0e #2ca02c #d62728 #9467bd #8c564b #e377c2 #7f7f7f #bcbd22 #17becf).each do |color| %>
-.colorseries-10-<%= n += 1 %>, .btn.colorseries-10-<%= n %>:hover, .label.colorseries-10-<%= n %>:hover {
-  *background-color: <%= color %>;
-  background-color: <%= color %>;
-  background-image: none;
-}
-<% end %>
-.colorseries-nil { }
-.label a {
-  color: inherit;
-}
-
-<% end %>
-
-<div class="tabbable">
-<ul class="nav nav-tabs">
-  <li class="active"><a href="#files" data-toggle="tab">Files (<%= @object.files ? @object.files.size : 0 %>)</a></li>
-  <li><a href="#provenance" data-toggle="tab">Provenance (<%= @provenance.size %>)</a></li>
-  <li><a href="#jobs" data-toggle="tab">Jobs (<%= @provenance.size %>)</a></li>
-  <li><a href="#sourcedata" data-toggle="tab">Source data (<%= @sourcedata.size %>)</a></li>
-  <li><a href="#owner-groups-resources" data-toggle="tab">Owner, groups, resources</a></li>
-  <li><a href="#provenance2" data-toggle="tab" id="prov-tab">Provenance graph</a></li>
-  <li><a href="#used-by" data-toggle="tab">Used by</a></li>
-</ul>
-
-<div class="tab-content">
-  <div id="files" class="tab-pane fade in active">
-    <table class="table table-bordered" style="table-layout: fixed">
-      <thead>
-        <tr>
-          <th>path</th>
-          <th>file</th>
-          <th style="width:1.5em">d/l</th>
-          <th style="width: 7em; text-align:right">size</th>
-        </tr>
-      </thead><tbody>
-        <% if @object then @object.files.sort_by{|f|f[1]}.each do |file| %>
-        <% file_path = "#{file[0]}/#{file[1]}" %>
-        <tr>
-          <td>
-            <%= file[0] %>
-          </td>
-
-          <td>
-            <%= link_to file[1], {controller: 'collections', action: 'show_file', uuid: @object.uuid, file: file_path, size: file[2], disposition: 'inline'}, {title: 'View in browser'} %>
-          </td>
-
-          <td>
-            <div style="display:inline-block">
-            <%= link_to raw('<i class="icon-download"></i>'), {controller: 'collections', action: 'show_file', uuid: @object.uuid, file: file_path, size: file[2], disposition: 'attachment'}, {class: 'label label-info', title: 'Download'} %>
-            </div>
-          </td>
-
-          <td style="text-align:right">
-            <%= raw(human_readable_bytes_html(file[2])) %>
-          </td>
-
-        </tr>
-        <% end; end %>
-      </tbody>
-    </table>
-  </div>
-  <div id="provenance" class="tab-pane fade">
-    <table class="topalign table table-bordered">
-      <thead>
-      </thead>
-      <tbody>
-
-	<% @provenance.reverse.each do |p| %>
-	<% j = p[:job] %>
-
-	<% if j %>
-
-	<tr class="job">
-	  <td style="padding-bottom: 3em">
-            <table class="table" style="margin-bottom: 0; background: #f0f0ff">
-	      <% j.script_parameters.each do |k,v| %>
-              <tr>
-                <td style="width: 20%">
-                  <%= k.to_s %>
-                </td><td style="width: 60%">
-	          <% if v and @output2job.has_key? v %>
-	          <tt class="label colorseries-10-<%= @output2colorindex[v] %>"><%= link_to_if_arvados_object v %></tt>
-                  <% else %>
-	          <span class="deemphasize"><%= link_to_if_arvados_object v %></span>
-                  <% end %>
-                </td><td style="text-align: center; width: 20%">
-                  <% if v
-                       if @protected[v]
-                         labelclass = 'success'
-                         labeltext = 'keep'
-                       else
-                         labelclass = @output2job.has_key?(v) ? 'warning' : 'danger'
-                         labeltext = 'cache'
-                       end %>
-
-	          <tt class="label label-<%= labelclass %>"><%= labeltext %></tt>
-                  <% end %>
-                </td>
-              </tr>
-	      <% end %>
-            </table>
-            <div style="text-align: center">
-              ↓
-              <br />
-	      <span class="label"><%= j.script %><br /><tt><%= link_to_if j.script_version.match(/[0-9a-f]{40}/), j.script_version, "https://arvados.org/projects/arvados/repository/revisions/#{j.script_version}/entry/crunch_scripts/#{j.script}" if j.script_version %></tt></span>
-              <br />
-              ↓
-              <br />
-	      <tt class="label colorseries-10-<%= @output2colorindex[p[:output]] %>"><%= link_to_if_arvados_object p[:output] %></tt>
-            </div>
-	  </td>
-          <td>
-	    <tt><span class="deemphasize">job:</span><br /><%= link_to_if_arvados_object j %><br /><span class="deemphasize"><%= j.submit_id %></span></tt>
-          </td>
-	</tr>
-
-	<% else %>
-	<tr>
-	  <td>
-	    <span class="label label-danger">lookup fail</span>
-	    <br />
-	    <tt class="deemphasize"><%= p[:target] %></tt>
-	  </td><td colspan="5">
-	  </td>
-	</tr>
-	<% end %>
-
-	<% end %>
-
-      </tbody>
-    </table>
-  </div>
-  <div id="provenance2" class="tab-pane fade">
-<script>
-    $(function() {
-      $('#prov-tab').on('shown', function() { provenance_sizing_fixup("provenance_graph", "provenance_svg"); });
-    })
-</script>
-   <%= render partial: 'application/svg_div', locals: {
-         divId: "provenance_graph", 
-         svgId: "provenance_svg", 
-         svg: @prov_svg } %>
-  </div>
-  <div id="jobs" class="tab-pane fade">
-    <table class="topalign table table-bordered">
-      <thead>
-	<tr class="contain-align-left">
-	  <th>
-	    job
-	  </th><th>
-	    version
-	  </th><th>
-	    status
-	  </th><th>
-	    start
-	  </th><th>
-	    finish
-	  </th><th>
-	    clock time
-	  </th>
-	</tr>
-      </thead>
-      <tbody>
-
-	<% @provenance.reverse.each do |p| %>
-	<% j = p[:job] %>
-
-	<% if j %>
-
-	<tr class="job">
-	  <td>
-	    <tt><%= j.uuid %></tt>
-	    <br />
-	    <tt class="deemphasize"><%= j.submit_id %></tt>
-	  </td><td>
-	    <%= j.script_version %>
-	  </td><td>
-            <span class="label <%= if j.success then 'label-success'; elsif j.running then 'label-primary'; else 'label-warning'; end %>">
-	      <%= j.success || j.running ? 'ok' : 'failed' %>
-            </span>
-	  </td><td>
-	    <%= j.started_at %>
-	  </td><td>
-	    <%= j.finished_at %>
-	  </td><td>
-	    <% if j.started_at and j.finished_at %>
-	    <%= raw(distance_of_time_in_words(j.started_at, j.finished_at).sub('about ','~').sub(' ',' ')) %>
-	    <% elsif j.started_at and j.running %>
-	    <%= raw(distance_of_time_in_words(j.started_at, Time.now).sub('about ','~').sub(' ',' ')) %> (running)
-	    <% end %>
-	  </td>
-	</tr>
-
-	<% else %>
-	<tr>
-	  <td>
-	    <span class="label label-danger">lookup fail</span>
-	    <br />
-	    <tt class="deemphasize"><%= p[:target] %></tt>
-	  </td><td colspan="4">
-	  </td>
-	</tr>
-	<% end %>
-
-	<% end %>
-
-      </tbody>
-    </table>
-  </div>
-  <div id="sourcedata" class="tab-pane fade">
-    <table class="table table-bordered table-striped">
-      <thead>
-	<tr class="contain-align-left">
-	  <th>
-	    collection
-	  </th><th class="data-size">
-	    data size
-	  </th><th>
-	    storage
-	  </th><th>
-	    origin
-	  </th>
-	</tr>
-      </thead>
-      <tbody>
-
-	<% @sourcedata.values.each do |sourcedata| %>
-
-	<tr class="collection">
-	  <td>
-	    <tt class="label"><%= sourcedata[:uuid] %></tt>
-	  </td><td class="data-size">
-	    <%= raw(human_readable_bytes_html(sourcedata[:collection].data_size)) if sourcedata[:collection] and sourcedata[:collection].data_size %>
-	  </td><td>
-	    <% if @protected[sourcedata[:uuid]] %>
-	    <span class="label label-success">keep</span>
-	    <% else %>
-	    <span class="label label-danger">cache</span>
-	    <% end %>
-	  </td><td>
-	    <% if sourcedata[:data_origins] %>
-	    <% sourcedata[:data_origins].each do |data_origin| %>
-	    <span class="deemphasize"><%= data_origin[0] %></span>
-	    <%= data_origin[2] %>
-	    <br />
-	    <% end %>
-	    <% end %>
-	  </td>
-	</tr>
-
-	<% end %>
-
-      </tbody>
-    </table>
-  </div>
-  <div id="owner-groups-resources" class="tab-pane fade">
-    <%= render :partial => 'application/arvados_object' %>
-  </div>
-</div>
-</div>
diff --git a/apps/workbench/app/views/pipeline_instances/compare.html.erb b/apps/workbench/app/views/pipeline_instances/compare.html.erb
index 8739c8d..79a1038 100644
--- a/apps/workbench/app/views/pipeline_instances/compare.html.erb
+++ b/apps/workbench/app/views/pipeline_instances/compare.html.erb
@@ -73,3 +73,15 @@
 <div class="row" style="padding: .5em">
 </div>
 <% end %>
+
+
+  <div style="text-align: center">
+    <span class="pipeline_color_legend" style="background: #88ff88">This pipeline</span> 
+    <span class="pipeline_color_legend" style="background: #8888ff">Comparison pipeline</span>
+    <span class="pipeline_color_legend" style="background: #88ffff">Shared by both pipelines</span>
+  </div>
+
+   <%= render partial: 'application/svg_div', locals: {
+         divId: "provenance_graph", 
+         svgId: "provenance_svg", 
+         svg: @prov_svg } %>
diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index f43ab6a..34a22aa 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -144,7 +144,7 @@ class ApplicationController < ActionController::Base
             conditions << nil
           elsif value.is_a? Array
             if value[0] == 'contains' and value.length == 2
-              conditions[0] << "and #{table_name}.#{attr} ilike ?"
+              conditions[0] << " and #{table_name}.#{attr} like ?"
               conditions << "%#{value[1]}%"
             else
               conditions[0] << " and #{table_name}.#{attr} in (?)"
diff --git a/services/api/app/controllers/arvados/v1/collections_controller.rb b/services/api/app/controllers/arvados/v1/collections_controller.rb
index 294e092..feed5ce 100644
--- a/services/api/app/controllers/arvados/v1/collections_controller.rb
+++ b/services/api/app/controllers/arvados/v1/collections_controller.rb
@@ -139,6 +139,65 @@ class Arvados::V1::CollectionsController < ApplicationController
     render json: visited
   end
 
+  def generate_used_by_edges(visited, uuid)
+    m = collection_uuid(uuid)
+    uuid = m if m
+
+    if not uuid or uuid.empty? or visited[uuid]
+      return ""
+    end
+
+    logger.debug "visiting #{uuid}"
+
+    if m  
+      # uuid is a collection
+      Collection.readable_by(current_user).where(uuid: uuid).each do |c|
+        visited[uuid] = c.as_api_response
+        visited[uuid][:files] = []
+        c.files.each do |f|
+          visited[uuid][:files] << f
+        end
+      end
+
+      if uuid == "d41d8cd98f00b204e9800998ecf8427e+0"
+        # special case for empty collection
+        return
+      end
+
+      Job.readable_by(current_user).where(["jobs.script_parameters like ?", "%#{uuid}%"]).each do |job|
+        generate_used_by_edges(visited, job.uuid)
+      end
+      
+    else
+      # uuid is something else
+      rsc = ArvadosModel::resource_class_for_uuid uuid
+      if rsc == Job
+        Job.readable_by(current_user).where(uuid: uuid).each do |job|
+          visited[uuid] = job.as_api_response
+          generate_used_by_edges(visited, job.output)
+        end
+      elsif rsc != nil
+        rsc.where(uuid: uuid).each do |r|
+          visited[uuid] = r.as_api_response
+        end
+      end
+    end
+
+    Link.readable_by(current_user).
+      where(tail_uuid: uuid, link_class: "provenance").
+      each do |link|
+      visited[link.uuid] = link.as_api_response
+      generate_used_by_edges(visited, link.head_uuid)
+    end
+
+    #puts "finished #{uuid}"
+  end
+
+  def used_by
+    visited = {}
+    generate_used_by_edges(visited, @object[:uuid])
+    render json: visited
+  end
 
   protected
   def find_object_by_uuid
diff --git a/services/api/config/routes.rb b/services/api/config/routes.rb
index e837e38..dffae7f 100644
--- a/services/api/config/routes.rb
+++ b/services/api/config/routes.rb
@@ -97,6 +97,7 @@ Server::Application.routes.draw do
       get '/user_agreements/signatures' => 'user_agreements#signatures'
       post '/user_agreements/sign' => 'user_agreements#sign'
       get '/collections/:uuid/provenance' => 'collections#provenance'
+      get '/collections/:uuid/used_by' => 'collections#used_by'
       resources :collections
       resources :links
       resources :nodes

commit 9e3bb9b984ff700fc3455f87437a8f1ac5841f0e
Merge: b2a75b1 4bc4165
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Tue Feb 4 10:25:40 2014 -0500

    Merge branch '1977-provenance-report' of git.clinicalfuture.com:arvados into 1977-provenance-report
    
    # Please enter a commit message to explain why this merge is necessary,
    # especially if it merges an updated upstream into a topic branch.
    #
    # Lines starting with '#' will be ignored, and an empty message aborts
    # the commit.


commit b2a75b1d0eab457047564a6901016c27a08fa36d
Author: Peter Amstutz <peter.amstutz at curoverse.com>
Date:   Tue Feb 4 10:25:23 2014 -0500

    Can now use 'contains' to query individual columns in where() queries, not just any: contains.

diff --git a/services/api/app/controllers/application_controller.rb b/services/api/app/controllers/application_controller.rb
index dcb9c0c..c379cee 100644
--- a/services/api/app/controllers/application_controller.rb
+++ b/services/api/app/controllers/application_controller.rb
@@ -137,6 +137,7 @@ class ApplicationController < ActionController::Base
       @where.each do |attr,value|
         if attr == :any
           if value.is_a?(Array) and
+              value.length == 2 and
               value[0] == 'contains' and
               model_class.columns.collect(&:name).index('name') then
             ilikes = []
@@ -154,8 +155,13 @@ class ApplicationController < ActionController::Base
             conditions[0] << " and #{table_name}.#{attr} is ?"
             conditions << nil
           elsif value.is_a? Array
-            conditions[0] << " and #{table_name}.#{attr} in (?)"
-            conditions << value
+            if value[0] == 'contains' and value.length == 2
+              conditions[0] << "and #{table_name}.#{attr} ilike ?"
+              conditions << "%#{value[1]}%"
+            else
+              conditions[0] << " and #{table_name}.#{attr} in (?)"
+              conditions << value
+            end
           elsif value.is_a? String or value.is_a? Fixnum or value == true or value == false
             conditions[0] << " and #{table_name}.#{attr}=?"
             conditions << value

-----------------------------------------------------------------------


hooks/post-receive
-- 




More information about the arvados-commits mailing list