Merge branch '5539-better-docker' closes #5539
[arvados.git] / services / api / app / controllers / arvados / v1 / groups_controller.rb
1 class Arvados::V1::GroupsController < ApplicationController
2
3   def self._contents_requires_parameters
4     params = _index_requires_parameters.
5       merge({
6               uuid: {
7                 type: 'string', required: false, default: nil
8               },
9             })
10     params.delete(:select)
11     params
12   end
13
14   def render_404_if_no_object
15     if params[:action] == 'contents'
16       if !params[:uuid]
17         # OK!
18         @object = nil
19         true
20       elsif @object
21         # Project group
22         true
23       elsif (@object = User.where(uuid: params[:uuid]).first)
24         # "Home" pseudo-project
25         true
26       else
27         super
28       end
29     else
30       super
31     end
32   end
33
34   def contents
35     load_searchable_objects
36     send_json({
37       :kind => "arvados#objectList",
38       :etag => "",
39       :self_link => "",
40       :offset => @offset,
41       :limit => @limit,
42       :items_available => @items_available,
43       :items => @objects.as_api_response(nil)
44     })
45   end
46
47   protected
48
49   def load_searchable_objects
50     all_objects = []
51     @items_available = 0
52
53     # Trick apply_where_limit_order_params into applying suitable
54     # per-table values. *_all are the real ones we'll apply to the
55     # aggregate set.
56     limit_all = @limit
57     offset_all = @offset
58     # save the orders from the current request as determined by load_param,
59     # but otherwise discard them because we're going to be getting objects
60     # from many models
61     request_orders = @orders.clone
62     @orders = []
63
64     [Group,
65      Job, PipelineInstance, PipelineTemplate,
66      Collection,
67      Human, Specimen, Trait].each do |klass|
68       # If the currently requested orders specifically match the
69       # table_name for the current klass, apply that order.
70       # Otherwise, order by recency.
71       request_order =
72         request_orders.andand.find { |r| r =~ /^#{klass.table_name}\./i } ||
73         klass.default_orders.join(", ")
74
75       @select = nil
76       where_conds = {}
77       where_conds[:owner_uuid] = @object.uuid if @object
78       if klass == Collection
79         @select = klass.selectable_attributes - ["manifest_text"]
80       elsif klass == Group
81         where_conds[:group_class] = "project"
82       end
83
84       @objects = klass.readable_by(*@read_users).
85         order(request_order).where(where_conds)
86       @limit = limit_all - all_objects.count
87       apply_where_limit_order_params klass
88       klass_object_list = object_list
89       klass_items_available = klass_object_list[:items_available] || 0
90       @items_available += klass_items_available
91       @offset = [@offset - klass_items_available, 0].max
92       all_objects += klass_object_list[:items]
93     end
94
95     @objects = all_objects
96     @limit = limit_all
97     @offset = offset_all
98   end
99
100 end