diff --git a/Bourreau/config/application.rb b/Bourreau/config/application.rb index 2db4d5ec6..eacf73b1b 100644 --- a/Bourreau/config/application.rb +++ b/Bourreau/config/application.rb @@ -17,8 +17,8 @@ class Application < Rails::Application config.eager_load_paths += Dir["#{config.root}/lib"] config.eager_load_paths += Dir["#{config.root}/lib/cbrain_task_generators"] - # CBRAIN Plugins load paths: add directories for each Userfile model - config.eager_load_paths += Dir[ "#{config.root}/cbrain_plugins/installed-plugins/userfiles/*" ] + # CBRAIN Plugins load paths: where userfiles defined by plugins are located (as links) + config.eager_load_paths += Dir[ "#{config.root}/cbrain_plugins/installed-plugins/userfiles" ] # CBRAIN Plugins load paths: add lib directory for standalone Ruby files config.eager_load_paths += Dir["#{config.root}/cbrain_plugins/installed-plugins/lib"] diff --git a/Bourreau/lib/bourreau_system_checks.rb b/Bourreau/lib/bourreau_system_checks.rb index abde039e1..a2cb8bccb 100644 --- a/Bourreau/lib/bourreau_system_checks.rb +++ b/Bourreau/lib/bourreau_system_checks.rb @@ -36,10 +36,8 @@ def self.puts(*args) #:nodoc: def self.a000_ensure_models_are_preloaded #:nodoc: # There's a piece of code at the end of each of these models # which forces the pre-load of all their subclasses. - Userfile.nil? ClusterTask.nil? # not PortalTask, which is only on the BrainPortal rails app BackgroundActivity.nil? - Userfile.preload_subclasses ClusterTask.preload_subclasses BackgroundActivity.preload_subclasses end diff --git a/BrainPortal/app/models/userfile.rb b/BrainPortal/app/models/userfile.rb index 3ae59dfab..40f334074 100644 --- a/BrainPortal/app/models/userfile.rb +++ b/BrainPortal/app/models/userfile.rb @@ -860,7 +860,7 @@ def public_path(public_file=nil) # # Returns a Pathname object. def self.view_path(partial_name=nil) - base = Pathname.new(CBRAIN::UserfilesPlugins_Dir) + self.to_s.underscore + "views" + base = Pathname.new(CBRAIN::ViewsPlugins_Dir) + self.to_s.underscore return base if partial_name.to_s.blank? partial_name = Pathname.new(partial_name.to_s).cleanpath raise "View partial path outside of userfile plugin." if partial_name.absolute? || partial_name.to_s =~ /\A\.\./ @@ -1188,27 +1188,5 @@ def check_exceeded_quota! true end - - - ################################################################## - # BOOT-TIME Support - ################################################################## - - public - - # Patch: pre-load all model files for the subclasses - def self.preload_subclasses - Dir.chdir(CBRAIN::UserfilesPlugins_Dir) do - Dir.glob("*").select { |dir| File.directory?(dir) }.each do |model_dir| - model_file = "#{model_dir}/#{model_dir}.rb" # e.g. "mp3_file/mp3_file.rb" for class Mp3File - next unless File.file?(model_file) - model = model_dir.classify - next if Object.const_defined? model # already loaded? Skip. - #puts_blue "Loading Userfile subclass #{model} from #{model_file} ..." - require_dependency "#{CBRAIN::UserfilesPlugins_Dir}/#{model_file}" - end - end - end - end diff --git a/BrainPortal/cbrain_plugins/installed-plugins/views/.gitignore b/BrainPortal/cbrain_plugins/installed-plugins/views/.gitignore new file mode 100644 index 000000000..d6b7ef32c --- /dev/null +++ b/BrainPortal/cbrain_plugins/installed-plugins/views/.gitignore @@ -0,0 +1,2 @@ +* +!.gitignore diff --git a/BrainPortal/config/application.rb b/BrainPortal/config/application.rb index 561889989..cd0387823 100644 --- a/BrainPortal/config/application.rb +++ b/BrainPortal/config/application.rb @@ -17,8 +17,8 @@ class Application < Rails::Application config.eager_load_paths += Dir["#{config.root}/lib"] config.eager_load_paths += Dir["#{config.root}/lib/cbrain_task_generators"] - # CBRAIN Plugins load paths: add directories for each Userfile model - config.eager_load_paths += Dir[ "#{config.root}/cbrain_plugins/installed-plugins/userfiles/*" ] + # CBRAIN Plugins load paths: where userfiles defined by plugins are located (as links) + config.eager_load_paths += Dir[ "#{config.root}/cbrain_plugins/installed-plugins/userfiles" ] # CBRAIN Plugins load paths: add lib directory for standalone Ruby files config.eager_load_paths += Dir["#{config.root}/cbrain_plugins/installed-plugins/lib"] diff --git a/BrainPortal/config/initializers/cbrain.rb b/BrainPortal/config/initializers/cbrain.rb index af9a05d12..3a69b1df6 100644 --- a/BrainPortal/config/initializers/cbrain.rb +++ b/BrainPortal/config/initializers/cbrain.rb @@ -47,6 +47,7 @@ class CBRAIN Plugins_Dir = "#{Rails.root.to_s}/cbrain_plugins" UserfilesPlugins_Dir = "#{Plugins_Dir}/installed-plugins/userfiles" TasksPlugins_Dir = "#{Plugins_Dir}/installed-plugins/cbrain_task" # singular; historical + ViewsPlugins_Dir = "#{Plugins_Dir}/installed-plugins/views" # Original integrator TaskDescriptorsPlugins_Dir = "#{Plugins_Dir}/installed-plugins/cbrain_task_descriptors" diff --git a/BrainPortal/lib/portal_system_checks.rb b/BrainPortal/lib/portal_system_checks.rb index 609fc3f7d..4b8a25cde 100644 --- a/BrainPortal/lib/portal_system_checks.rb +++ b/BrainPortal/lib/portal_system_checks.rb @@ -37,10 +37,8 @@ def self.puts(*args) #:nodoc: def self.a000_ensure_models_are_preloaded #:nodoc: # There's a piece of code at the end of each of these models # which forces the pre-load of all their subclasses. - Userfile.nil? PortalTask.nil? # not ClusterTask, which is only on the Bourreau rails app BackgroundActivity.nil? - Userfile.preload_subclasses PortalTask.preload_subclasses BackgroundActivity.preload_subclasses end diff --git a/BrainPortal/lib/tasks/cbrain_plugins.rake b/BrainPortal/lib/tasks/cbrain_plugins.rake index 8bb997d6b..f311a2827 100644 --- a/BrainPortal/lib/tasks/cbrain_plugins.rake +++ b/BrainPortal/lib/tasks/cbrain_plugins.rake @@ -6,7 +6,7 @@ namespace :cbrain do namespace :plugins do - verbose = false # TODO make a command-line param? + verbose = ENV['CBRAIN_RAKE_VERBOSE'].present? # TODO make a command-line param? # Unfortunately we don't have access to cbrain.rb where some useful constants are defined in the # CBRAIN class, such as CBRAIN::TasksPlugins_Dir ; if we ever change where plugins are stored, we @@ -14,6 +14,7 @@ namespace :cbrain do plugins_dir = Rails.root + "cbrain_plugins" installed_plugins_dir = plugins_dir + "installed-plugins" userfiles_plugins_dir = installed_plugins_dir + "userfiles" + views_plugins_dir = installed_plugins_dir + "views" tasks_plugins_dir = installed_plugins_dir + "cbrain_task" descriptors_plugins_dir = installed_plugins_dir + "cbrain_task_descriptors" boutiques_plugins_dir = installed_plugins_dir + "boutiques_descriptors" @@ -83,12 +84,12 @@ namespace :cbrain do Dir.chdir(package) do # Setup a single unit (userfiles, tasks or descriptors) - setup = lambda do |glob, name, directory, condition: nil, after: nil| - files = Dir.glob(glob) - files.select!(&condition) if condition - puts "Found #{files.size} #{name}(s) to set up..." if verbose - files.each do |u_slash_f| - plugin = Pathname.new(u_slash_f).basename.to_s + setup = lambda do |glob, name, directory, condition: nil, linkname: nil, after: nil| + entries = Dir.glob(glob) + entries.select!(&condition) if condition + puts "Found #{entries.size} #{name}(s) to set up..." if verbose + entries.each do |u_slash_f| + plugin = linkname ? linkname.(u_slash_f) : Pathname.new(u_slash_f).basename.to_s symlink_location = directory + plugin plugin_location = plugins_dir + package + u_slash_f symlink_value = plugin_location.relative_path_from(symlink_location.parent) @@ -132,40 +133,48 @@ namespace :cbrain do end # Setup each userfile plugin - setup.('userfiles/*', 'userfile', userfiles_plugins_dir, - condition: lambda { |f| File.directory?(f) } - ) erase_dead_symlinks.('userfile', userfiles_plugins_dir) + setup.('userfiles/*/*.rb', 'userfile', userfiles_plugins_dir, + condition: lambda { |f| File.file?(f) } + ) + + # Setup the views of each userfile + if Rails.root.to_s =~ /\/BrainPortal$/ # not needed on Bourreaux + erase_dead_symlinks.('views', views_plugins_dir) + setup.('userfiles/*/views', 'views', views_plugins_dir, + linkname: lambda { |f| Pathname.new(f).parent.basename.to_s } + ) + end # Setup each cbrain_task plugin + erase_dead_symlinks.('task', tasks_plugins_dir) setup.('cbrain_task/*', 'task', tasks_plugins_dir, condition: lambda { |f| File.directory?(f) }, after: lambda do |symlink_location| File.symlink "cbrain_task_class_loader.rb", "#{symlink_location}.rb" end ) - erase_dead_symlinks.('task', tasks_plugins_dir) # Setup each cbrain_task descriptor plugin + erase_dead_symlinks.('descriptor', descriptors_plugins_dir) setup.('cbrain_task_descriptors/*', 'descriptor', descriptors_plugins_dir, condition: lambda { |f| File.extname(f) == '.json' }, after: lambda do |symlink_location| File.symlink "cbrain_task_descriptor_loader.rb", "#{symlink_location.sub(/.json$/, '.rb')}" end ) - erase_dead_symlinks.('descriptor', descriptors_plugins_dir) # Setup each boutiques descriptor plugin (new integrator) + erase_dead_symlinks.('boutiques', boutiques_plugins_dir) setup.('boutiques_descriptors/*', 'boutiques', boutiques_plugins_dir, condition: lambda { |f| File.extname(f) == '.json' }, ) - erase_dead_symlinks.('boutiques', boutiques_plugins_dir) # Setup each ruby lib file + erase_dead_symlinks.('lib', lib_plugins_dir) setup.('lib/*', 'lib', lib_plugins_dir, condition: lambda { |f| File.extname(f) == '.rb' }, ) - erase_dead_symlinks.('lib', lib_plugins_dir) end # chdir package end # each package @@ -190,20 +199,26 @@ namespace :cbrain do puts "Adjusting paths to public assets for tasks and userfiles..." if verbose Dir.chdir(public_userfiles) do - userfiles_public_dirs = Dir.glob(userfiles_plugins_dir + "*/views/public") + userfiles_public_dirs = Dir.glob(views_plugins_dir + "*/public") if userfiles_public_dirs.empty? puts "No public assets made available by any userfiles." if verbose else puts "Found #{userfiles_public_dirs.size} userfile(s) with public assets to set up..." if verbose end - userfiles_public_dirs.each do |fullpath| # "/a/b/rails/cbrain_plugins/installed-plugins/userfiles/text_file/views/public" - relpath = Pathname.new(fullpath).relative_path_from(public_tasks) # ../(...)/cbrain_plugins/installed-plugins/userfiles/text_file/views/public - filename = relpath.parent.parent.basename # "text_file" - if File.exists?(filename) - puts "-> Assets for userfile already set up: '#{filename}'." if verbose - logger.('AssetSymlinkIsOk','(installed)','userfile',filename) if verbose - next + userfiles_public_dirs.each do |fullpath| # "/a/b/rails/cbrain_plugins/installed-plugins/views/text_file/public" + relpath = Pathname.new(fullpath).relative_path_from(public_userfiles) # ../(...)/cbrain_plugins/installed-plugins/views/text_file/public + filename = relpath.parent.basename # "text_file" + if File.exists?(filename) || File.symlink?(filename) + if File.symlink?(filename) && (File.readlink(filename) == relpath.to_s) + puts "-> Assets for userfile already set up: '#{filename}'." if verbose + logger.('AssetSymlinkIsOk','(installed)','userfile',filename) if verbose + next + else + puts "-> Something is in the way for assets for userfile: '#{filename}'." if verbose + logger.('AssetSymlinkBad','(installed)','userfile',filename) if verbose + File.unlink(filename) rescue true # let's try to cleanup.. if that fails, and exception will happen later during symlink + end end puts "-> Creating assets symbolic link for userfile '#{filename}'." if verbose logger.('MakeAssetSymlink','(installed)','userfile',filename) @@ -222,10 +237,16 @@ namespace :cbrain do tasks_public_dirs.each do |fullpath| # "/a/b/rails/cbrain_plugins/installed-plugins/cbrain_tasks/diagnostics/views/public" relpath = Pathname.new(fullpath).relative_path_from(public_tasks) # ../(...)/cbrain_plugins/cbrain_tasks/diagnostics/views/public taskname = relpath.parent.parent.basename # "diagnostics" - if File.exists?(taskname) - puts "-> Assets for task already set up: '#{taskname}'." if verbose - logger.('AssetSymlinkIsOk','(installed)','task',taskname) if verbose - next + if File.exists?(taskname) || File.symlink?(taskname) + if File.symlink?(taskname) && (File.readlink(taskname) == relpath.to_s) + puts "-> Assets for task already set up: '#{taskname}'." if verbose + logger.('AssetSymlinkIsOk','(installed)','task',taskname) if verbose + next + else + puts "-> Something is in the way for assets for tasks: '#{taskname}'." if verbose + logger.('AssetSymlinkBad','(installed)','task',taskname) if verbose + File.unlink(taskname) rescue true # let's try to cleanup.. if that fails, and exception will happen later during symlink + end end puts "-> Creating assets symbolic link for task '#{taskname}'." if verbose logger.('MakeAssetSymlink','(installed)','task',taskname) @@ -299,6 +320,7 @@ namespace :cbrain do end erase.('userfile', userfiles_plugins_dir) + erase.('views', views_plugins_dir) erase.('task', tasks_plugins_dir) erase.('descriptor', descriptors_plugins_dir) erase.('boutiques', boutiques_plugins_dir)