X-Git-Url: https://git.arvados.org/arvados.git/blobdiff_plain/1b3750c9ffbec7a76b374023188c5c13882dc651..66da5859254325690a78512d03b6b02e3f69a237:/apps/workbench/app/controllers/application_controller.rb diff --git a/apps/workbench/app/controllers/application_controller.rb b/apps/workbench/app/controllers/application_controller.rb index ade586c474..e39d7760f4 100644 --- a/apps/workbench/app/controllers/application_controller.rb +++ b/apps/workbench/app/controllers/application_controller.rb @@ -12,7 +12,6 @@ class ApplicationController < ActionController::Base before_filter :check_user_agreements, except: ERROR_ACTIONS before_filter :check_user_notifications, except: ERROR_ACTIONS before_filter :find_object_by_uuid, except: [:index] + ERROR_ACTIONS - before_filter :check_my_folders, :except => ERROR_ACTIONS theme :select_theme begin @@ -121,21 +120,21 @@ class ApplicationController < ActionController::Base end def update - updates = params[@object.class.to_s.underscore.singularize.to_sym] - updates.keys.each do |attr| + @updates ||= params[@object.class.to_s.underscore.singularize.to_sym] + @updates.keys.each do |attr| if @object.send(attr).is_a? Hash - if updates[attr].is_a? String - updates[attr] = Oj.load updates[attr] + if @updates[attr].is_a? String + @updates[attr] = Oj.load @updates[attr] end if params[:merge] || params["merge_#{attr}".to_sym] # Merge provided Hash with current Hash, instead of # replacing. - updates[attr] = @object.send(attr).with_indifferent_access. - deep_merge(updates[attr].with_indifferent_access) + @updates[attr] = @object.send(attr).with_indifferent_access. + deep_merge(@updates[attr].with_indifferent_access) end end end - if @object.update_attributes updates + if @object.update_attributes @updates show else self.render_error status: 422 @@ -404,15 +403,6 @@ class ApplicationController < ActionController::Base } } - def check_my_folders - @my_top_level_folders = lambda do - @top_level_folders ||= Group. - filter([['group_class','=','folder'], - ['owner_uuid','=',current_user.uuid]]). - sort_by { |x| x.name || '' } - end - end - def check_user_notifications @notification_count = 0 @notifications = [] @@ -432,4 +422,136 @@ class ApplicationController < ActionController::Base @notification_count = '' end end + + helper_method :my_folders + def my_folders + return @my_folders if @my_folders + @my_folders = [] + root_of = {} + Group.filter([['group_class','=','folder']]).each do |g| + root_of[g.uuid] = g.owner_uuid + @my_folders << g + end + done = false + while not done + done = true + root_of = root_of.each_with_object({}) do |(child, parent), h| + if root_of[parent] + h[child] = root_of[parent] + done = false + else + h[child] = parent + end + end + end + @my_folders = @my_folders.select do |g| + root_of[g.uuid] == current_user.uuid + end + end + + # helper method to get links for given object or uuid + helper_method :links_for_object + def links_for_object object_or_uuid + uuid = object_or_uuid.is_a?(String) ? object_or_uuid : object_or_uuid.uuid + preload_links_for_objects([object_or_uuid]) + @all_links_for[uuid] + end + + # helper method to preload links for given objects and uuids + helper_method :preload_links_for_objects + def preload_links_for_objects objects_and_uuids + uuids = objects_and_uuids.collect { |x| x.is_a?(String) ? x : x.uuid } + @all_links_for ||= {} + if not uuids.select { |x| @all_links_for[x].nil? }.any? + # already preloaded for all of these uuids + return + end + uuids.each do |x| + @all_links_for[x] = [] + end + # TODO: make sure we get every page of results from API server + Link.filter([['head_uuid','in',uuids]]).each do |link| + @all_links_for[link.head_uuid] << link + end + end + + # helper method to get a certain number of objects of a specific type + # this can be used to replace any uses of: "dataclass.limit(n)" + helper_method :get_objects_of_type + def get_objects_of_type dataclass, size + # if the objects_map_for has a value for this dataclass, and the size used + # to retrieve those objects is greater than equal to size, return it + size_key = "#{dataclass}_size" + if @objects_map_for && @objects_map_for[dataclass] && @objects_map_for[size_key] && + (@objects_map_for[size_key] >= size) + return @objects_map_for[dataclass] + end + + @objects_map_for = {} + @objects_map_for[dataclass] = dataclass.limit(size) + @objects_map_for[size_key] = size + + return @objects_map_for[dataclass] + end + + # helper method to get collections for the given uuid + helper_method :get_collections + def get_collections uuid + preload_collections([uuid]) + @all_collections_for[uuid] + end + + # helper method to preload collections for the given uuids + helper_method :preload_collections + def preload_collections uuids + @all_collections_for ||= {} + if not uuids.select { |x| @all_collections_for[x].nil? }.any? + # already preloaded for all of these uuids + return + end + + uuids.each do |x| + @all_collections_for[x] = [] + end + + # TODO: make sure we get every page of results from API server + Collection.where(uuid: uuids).each do |collection| + @all_collections_for[collection.uuid] << collection + end + end + + # helper method to get log collections for the given log + helper_method :get_log_collections + def get_log_collections log + fixup = /([a-f0-9]{32}\+\d+)(\+?.*)/.match(log) + uuid = fixup[1] + preload_log_collections([uuid]) + @all_log_collections_for[uuid] + end + + # helper method to preload collections for the given uuids + helper_method :preload_log_collections + def preload_log_collections logs + uuids = [] + logs.each do |log| + fixup = /([a-f0-9]{32}\+\d+)(\+?.*)/.match(log) + uuids << fixup[1] + end + + @all_log_collections_for ||= {} + if not uuids.select { |x| @all_log_collections_for[x].nil? }.any? + # already preloaded for all of these uuids + return + end + + uuids.each do |x| + @all_log_collections_for[x] = [] + end + + # TODO: make sure we get every page of results from API server + Collection.where(uuid: uuids).each do |collection| + @all_log_collections_for[collection.uuid] << collection + end + end + end