2872: Rearrange top nav with breadcrumbs/projects bar.
[arvados.git] / apps / workbench / app / controllers / actions_controller.rb
1 class ActionsController < ApplicationController
2
3   @@exposed_actions = {}
4   def self.expose_action method, &block
5     @@exposed_actions[method] = true
6     define_method method, block
7   end
8
9   def model_class
10     ArvadosBase::resource_class_for_uuid(params[:uuid])
11   end
12
13   def post
14     params.keys.collect(&:to_sym).each do |param|
15       if @@exposed_actions[param]
16         return self.send(param)
17       end
18     end
19     redirect_to :back
20   end
21
22   expose_action :copy_selections_into_project do
23     link_selections = Link.filter([['uuid','in',params["selection"]]])
24     link_uuids = link_selections.collect(&:uuid)
25
26     # Given a link uuid, we'll add the link's head_uuid. Given another
27     # type, we'll add the object itself.
28     uuids_to_add = params["selection"] - link_uuids
29     uuids_to_add += link_selections.collect(&:head_uuid)
30
31     # Skip anything that's already here.
32     already_named = Link.
33       filter([['tail_uuid','=',@object.uuid],
34               ['head_uuid','in',uuids_to_add],
35               ['link_class','=','name']]).
36       collect(&:head_uuid)
37     uuids_to_add -= already_named
38
39     # Given a name link, we'll try to add the linked object using the
40     # same name.
41     name_for = {}
42     link_selections.
43       select { |x| x.link_class == 'name' }.
44       each do |link|
45       name_for[link.head_uuid] = link.name
46     end
47
48     uuids_to_add.each do |s|
49       name = name_for[s] || s
50       begin
51         Link.create(tail_uuid: @object.uuid,
52                     head_uuid: s,
53                     link_class: 'name',
54                     name: name)
55       rescue
56         Link.create(tail_uuid: @object.uuid,
57                     head_uuid: s,
58                     link_class: 'name',
59                     name: name + " (#{Time.now.localtime})")
60       end
61     end
62     redirect_to @object
63   end
64
65   expose_action :combine_selected_files_into_collection do
66     lst = []
67     files = []
68     params["selection"].each do |s|
69       m = CollectionsHelper.match(s)
70       if m and m[1] and m[2]
71         lst.append(m[1] + m[2])
72         files.append(m)
73       end
74     end
75
76     collections = Collection.where(uuid: lst)
77
78     chash = {}
79     collections.each do |c|
80       c.reload()
81       chash[c.uuid] = c
82     end
83
84     combined = ""
85     files.each do |m|
86       mt = chash[m[1]+m[2]].manifest_text
87       if m[4]
88         IO.popen(['arv-normalize', '--extract', m[4][1..-1]], 'w+b') do |io|
89           io.write mt
90           io.close_write
91           while buf = io.read(2**20)
92             combined += buf
93           end
94         end
95       else
96         combined += chash[m[1]+m[2]].manifest_text
97       end
98     end
99
100     normalized = ''
101     IO.popen(['arv-normalize'], 'w+b') do |io|
102       io.write combined
103       io.close_write
104       while buf = io.read(2**20)
105         normalized += buf
106       end
107     end
108
109     require 'digest/md5'
110
111     d = Digest::MD5.new()
112     d << normalized
113     newuuid = "#{d.hexdigest}+#{normalized.length}"
114
115     env = Hash[ENV].
116       merge({
117               'ARVADOS_API_HOST' =>
118               arvados_api_client.arvados_v1_base.
119               sub(/\/arvados\/v1/, '').
120               sub(/^https?:\/\//, ''),
121               'ARVADOS_API_TOKEN' => Thread.current[:arvados_api_token],
122               'ARVADOS_API_HOST_INSECURE' =>
123               Rails.configuration.arvados_insecure_https ? 'true' : 'false'
124             })
125
126     IO.popen([env, 'arv-put', '--raw'], 'w+b') do |io|
127       io.write normalized
128       io.close_write
129       while buf = io.read(2**20)
130
131       end
132     end
133
134     newc = Collection.new({:uuid => newuuid, :manifest_text => normalized})
135     newc.save!
136
137     chash.each do |k,v|
138       l = Link.new({
139                      tail_uuid: k,
140                      head_uuid: newuuid,
141                      link_class: "provenance",
142                      name: "provided"
143                    })
144       l.save!
145     end
146
147     redirect_to controller: 'collections', action: :show, id: newc.uuid
148   end
149
150 end