X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/1b7d5cef1b7890994826a44102b589124a2a2340..2d911a46e2698f18200bf2170bdb4c18452439a1:/apps/workbench/app/controllers/actions_controller.rb diff --git a/apps/workbench/app/controllers/actions_controller.rb b/apps/workbench/app/controllers/actions_controller.rb index 8a817f03cd..347644bdbd 100644 --- a/apps/workbench/app/controllers/actions_controller.rb +++ b/apps/workbench/app/controllers/actions_controller.rb @@ -1,97 +1,198 @@ class ActionsController < ApplicationController - skip_before_filter :find_object_by_uuid, only: :post + skip_filter :require_thread_api_token, only: [:report_issue_popup, :report_issue] + skip_filter :check_user_agreements, only: [:report_issue_popup, :report_issue] - def combine_selected_files_into_collection - lst = [] - files = [] - params["selection"].each do |s| - m = CollectionsHelper.match(s) - if m and m[1] and m[2] - lst.append(m[1] + m[2]) - files.append(m) - end - end + @@exposed_actions = {} + def self.expose_action method, &block + @@exposed_actions[method] = true + define_method method, block + end - collections = Collection.where(uuid: lst) + def model_class + ArvadosBase::resource_class_for_uuid(params[:uuid]) + end - chash = {} - collections.each do |c| - c.reload() - chash[c.uuid] = c + def show + @object = model_class.andand.find(params[:uuid]) + if @object.is_a? Link and + @object.link_class == 'name' and + ArvadosBase::resource_class_for_uuid(@object.head_uuid) == Collection + redirect_to collection_path(id: @object.uuid) + elsif @object + redirect_to @object + else + raise ActiveRecord::RecordNotFound end + end - combined = "" - files.each do |m| - mt = chash[m[1]+m[2]].manifest_text - if m[4] - IO.popen(['arv-normalize', '--extract', m[4][1..-1]], 'w+b') do |io| - io.write mt - io.close_write - while buf = io.read(2**20) - combined += buf - end - end - else - combined += chash[m[1]+m[2]].manifest_text + def post + params.keys.collect(&:to_sym).each do |param| + if @@exposed_actions[param] + return self.send(param) end end + redirect_to :back + end - normalized = '' - IO.popen(['arv-normalize'], 'w+b') do |io| - io.write combined - io.close_write - while buf = io.read(2**20) - normalized += buf - end - end + expose_action :copy_selections_into_project do + move_or_copy :copy + end - require 'digest/md5' + expose_action :move_selections_into_project do + move_or_copy :move + end - d = Digest::MD5.new() - d << normalized - newuuid = "#{d.hexdigest}+#{normalized.length}" + def move_or_copy action + uuids_to_add = params["selection"] + uuids_to_add = [ uuids_to_add ] unless uuids_to_add.is_a? Array + uuids_to_add. + collect { |x| ArvadosBase::resource_class_for_uuid(x) }. + uniq. + each do |resource_class| + resource_class.filter([['uuid','in',uuids_to_add]]).each do |src| + if resource_class == Collection and not Collection.attribute_info.include?(:name) + dst = Link.new(owner_uuid: @object.uuid, + tail_uuid: @object.uuid, + head_uuid: src.uuid, + link_class: 'name', + name: src.uuid) + else + case action + when :copy + dst = src.dup + if dst.respond_to? :'name=' + if dst.name + dst.name = "Copy of #{dst.name}" + else + dst.name = "Copy of unnamed #{dst.class_for_display.downcase}" + end + end + if resource_class == Collection + dst.manifest_text = Collection.select([:manifest_text]).where(uuid: src.uuid).first.manifest_text + end + when :move + dst = src + else + raise ArgumentError.new "Unsupported action #{action}" + end + dst.owner_uuid = @object.uuid + dst.tail_uuid = @object.uuid if dst.class == Link + end + begin + dst.save! + rescue + dst.name += " (#{Time.now.localtime})" if dst.respond_to? :name= + dst.save! + end + end + end + redirect_to @object + end + def arv_normalize mt, *opts + r = "" env = Hash[ENV]. - merge({ - 'ARVADOS_API_HOST' => - $arvados_api_client.arvados_v1_base. + merge({'ARVADOS_API_HOST' => + arvados_api_client.arvados_v1_base. sub(/\/arvados\/v1/, ''). sub(/^https?:\/\//, ''), - 'ARVADOS_API_TOKEN' => Thread.current[:arvados_api_token], + 'ARVADOS_API_TOKEN' => 'x', 'ARVADOS_API_HOST_INSECURE' => Rails.configuration.arvados_insecure_https ? 'true' : 'false' }) - - IO.popen([env, 'arv-put', '--raw'], 'w+b') do |io| - io.write normalized + IO.popen([env, 'arv-normalize'] + opts, 'w+b') do |io| + io.write mt io.close_write - while buf = io.read(2**20) + while buf = io.read(2**16) + r += buf + end + end + r + end + expose_action :combine_selected_files_into_collection do + uuids = [] + pdhs = [] + files = [] + params["selection"].each do |s| + a = ArvadosBase::resource_class_for_uuid s + if a == Link + begin + if (m = CollectionsHelper.match(Link.find(s).head_uuid)) + pdhs.append(m[1] + m[2]) + files.append(m) + end + rescue + end + elsif (m = CollectionsHelper.match(s)) + pdhs.append(m[1] + m[2]) + files.append(m) + elsif (m = CollectionsHelper.match_uuid_with_optional_filepath(s)) + uuids.append(m[1]) + files.append(m) end end - newc = Collection.new({:uuid => newuuid, :manifest_text => normalized}) + pdhs = pdhs.uniq + uuids = uuids.uniq + chash = {} + + Collection.select([:uuid, :manifest_text]).where(uuid: uuids).each do |c| + chash[c.uuid] = c + end + + Collection.select([:portable_data_hash, :manifest_text]).where(portable_data_hash: pdhs).each do |c| + chash[c.portable_data_hash] = c + end + + combined = "" + files.each do |m| + mt = chash[m[1]+m[2]].andand.manifest_text + if not m[4].nil? and m[4].size > 1 + combined += arv_normalize mt, '--extract', m[4][1..-1] + else + combined += mt + end + end + + normalized = arv_normalize combined + newc = Collection.new({:manifest_text => normalized}) + newc.name = newc.name || "Collection created at #{Time.now.localtime}" newc.save! chash.each do |k,v| l = Link.new({ tail_uuid: k, - head_uuid: newuuid, + head_uuid: newc.uuid, link_class: "provenance", name: "provided" }) l.save! end - redirect_to controller: 'collections', action: :show, id: newc.uuid + action_data = JSON.parse(params['action_data']) if params['action_data'] + if action_data && action_data['selection_param'].eql?('project') + redirect_to :back + else + redirect_to url_for(controller: 'collections', action: :show, id: newc.uuid) + end end - def post - if params["combine_selected_files_into_collection"] - combine_selected_files_into_collection - else - redirect_to :back + def report_issue_popup + respond_to do |format| + format.js + format.html end end + + def report_issue + logger.warn "report_issue: #{params.inspect}" + + respond_to do |format| + IssueReporter.send_report(current_user, params).deliver + format.js {render nothing: true} + end + end + end