From 6542db909c250c39479d4fea5e80de8a0a558750 Mon Sep 17 00:00:00 2001 From: "karel.picman@lbcfree.net" Date: Thu, 18 Jun 2020 16:29:31 +0200 Subject: [PATCH] Basic functionality --- lib/redmine_dmsf/webdav/base_resource.rb | 43 +++++++++------ lib/redmine_dmsf/webdav/dmsf_resource.rb | 58 ++++++++++++++++++--- lib/redmine_dmsf/webdav/index_resource.rb | 4 +- lib/redmine_dmsf/webdav/project_resource.rb | 11 ++++ 4 files changed, 90 insertions(+), 26 deletions(-) diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb index 5def382f..764d9879 100644 --- a/lib/redmine_dmsf/webdav/base_resource.rb +++ b/lib/redmine_dmsf/webdav/base_resource.rb @@ -34,7 +34,7 @@ module RedmineDmsf raise NotFound if Setting.plugin_redmine_dmsf['dmsf_webdav'].blank? @project = nil @public_path = "#{options[:root_uri_path]}#{path}" - super(path, request, response, options) + super path, request, response, options end DIR_FILE = "%s%s%s%s" @@ -81,16 +81,17 @@ module RedmineDmsf new_path = @path new_path = new_path + '/' unless new_path[-1,1] == '/' new_path = '/' + new_path unless new_path[0,1] == '/' - @__proxy.class.new("#{new_path}#{name}", request, response, @options.merge(user: @user)) + @__proxy.class.new "#{new_path}#{name}", request, response, @options.merge(user: @user) end def child_project(p) project_display_name = ProjectResource.create_project_name(p) new_path = @path + #new_path = +'/' new_path = new_path + '/' unless new_path[-1,1] == '/' new_path = '/' + new_path unless new_path[0,1] == '/' new_path += project_display_name - @__proxy.class.new(new_path, request, response, @options.merge(user: @user)) + @__proxy.class.new new_path, request, response, @options.merge(user: @user) end def parent @@ -110,26 +111,35 @@ module RedmineDmsf protected def basename - File.basename(@path) + File.basename @path end # Return instance of Project based on the path def project unless @project - pinfo = @path.split('/').drop(1) - if pinfo.length > 0 - if Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] - if pinfo.first =~ /(\d+)$/ - @project = Project.find_by(id: $1) - Rails.logger.error("No project found on path '#{@path}'") unless @project - end - else - begin - @project = Project.find(pinfo.first) - rescue => e - Rails.logger.error e.message + i = 1 + while true + pinfo = @path.split('/').drop(i) + if pinfo.length > 0 + if Setting.plugin_redmine_dmsf['dmsf_webdav_use_project_names'] + if pinfo.first =~ /(\d+)$/ + prj = Project.visible.find_by(id: $1) + Rails.logger.error("No project found on path '#{@path}'") unless prj + end + else + begin + scope = Project.visible.where(identifier: pinfo.first) + scope = scope.where(parent_id: @project.id) if @project + prj = scope.first + rescue => e + Rails.logger.error e.message + end end end + break unless prj + i = i + 1 + @project = prj + prj = nil end end @project @@ -137,6 +147,7 @@ module RedmineDmsf # Make it easy to find the path without project in it. def projectless_path + # TODO: '/' + @path.split('/').drop(2).join('/') end diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb index 63f24460..4a308e4c 100644 --- a/lib/redmine_dmsf/webdav/dmsf_resource.rb +++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb @@ -31,12 +31,13 @@ module RedmineDmsf def initialize(path, request, response, options) @folder = nil @file = nil + @subproject = nil super path, request, response, options end # Here we make sure our folder and file methods are not aliased - it should shave a few cycles off of processing def setup - @skip_alias |= [ :folder, :file ] + @skip_alias |= [ :folder, :file, :subproject ] end # Gather collection of objects that denote current entities child entities @@ -46,13 +47,29 @@ module RedmineDmsf def children unless @children @children = [] - if collection? + if folder + # Folders folder.dmsf_folders.visible.pluck(:title).each do |title| @children.push child(title) end + # Files folder.dmsf_files.visible.pluck(:name).each do |name| @children.push child(name) end + elsif subproject + # Projects + subproject.children.visible.select(:id, :identifier, :name).has_module(:dmsf).where( + Project.allowed_to_condition(User.current, :view_dmsf_folders)).find_each do |p| + @children << child_project(p) + end + # Folders + subproject.dmsf_folders.visible.pluck(:title).each do |title| + @children.push child(title) + end + # Files + subproject.dmsf_files.visible.pluck(:name).each do |name| + @children.push child(name) + end end end @children @@ -61,17 +78,17 @@ module RedmineDmsf # Does the object exist? # If it is either a folder or a file, then it exists def exist? - project && project.module_enabled?('dmsf') && (folder || file) && + project && project.module_enabled?('dmsf') && (folder || file || subproject) && (User.current.admin? || User.current.allowed_to?(:view_dmsf_folders, project)) end def really_exist? - project && project.module_enabled?('dmsf') && (folder || file) + project && project.module_enabled?('dmsf') && (folder || file || subproject) end # Is this entity a folder? def collection? - !folder.nil? + folder || subproject end # Check if current entity is a folder and return DmsfFolder object if found (nil if not) @@ -86,12 +103,27 @@ module RedmineDmsf # Check if the current entity exists as a file (DmsfFile), and returns corresponding object if found (nil otherwise) def file unless @file - return nil unless project # Again if entity project is nil, it cannot exist in context of this object - @file = DmsfFile.find_file_by_name(project, parent.folder, basename) + @file = DmsfFile.find_file_by_name(project, parent.folder, basename) if project end @file end + def subproject + unless @subproject + @subproject = Project.visible.where(parent_id: parent_project.id, name: basename).first if parent_project + end + @subproject + end + + def parent_project + unless @parent_project + if /\/(.+)\/#{project.identifier}\/?$/.match(@path) + @parent_project = Project.visible.where(identifier: $1).first + end + end + @parent_project + end + # Return the content type of file # will return inode/directory for any collections, and appropriate for File entities def content_type @@ -99,6 +131,8 @@ module RedmineDmsf 'inode/directory' elsif file && file.last_revision file.last_revision.detect_content_type + elsif subproject + 'inode/directory' else NotFound end @@ -109,6 +143,8 @@ module RedmineDmsf folder.created_at elsif file file.created_at + elsif subproject + subproject.created_on else NotFound end @@ -119,6 +155,8 @@ module RedmineDmsf folder.updated_at elsif file && file.last_revision file.last_revision.updated_at + elsif subproject + subproject.updated_on else NotFound end @@ -135,7 +173,11 @@ module RedmineDmsf end def special_type - l(:field_folder) if folder + if folder + l(:field_folder) + elsif subproject + l(:field_project) + end end # Process incoming GET request diff --git a/lib/redmine_dmsf/webdav/index_resource.rb b/lib/redmine_dmsf/webdav/index_resource.rb index c85bcf6f..9b26eac1 100644 --- a/lib/redmine_dmsf/webdav/index_resource.rb +++ b/lib/redmine_dmsf/webdav/index_resource.rb @@ -32,9 +32,9 @@ module RedmineDmsf def children unless @projects @projects = [] - Project.select(:id, :identifier, :name).has_module(:dmsf).where( + Project.visible.select(:id, :identifier, :name).has_module(:dmsf).where( Project.allowed_to_condition( - User.current, :view_dmsf_folders)).order('lft').find_each do |p| + User.current, :view_dmsf_folders)).find_each do |p| @projects << child_project(p) end end diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb index 2a099119..cd3f0968 100644 --- a/lib/redmine_dmsf/webdav/project_resource.rb +++ b/lib/redmine_dmsf/webdav/project_resource.rb @@ -34,9 +34,20 @@ module RedmineDmsf unless @children @children = [] if project + # Sub-projects + # project.children.select(:id, :identifier, :name).has_module(:dmsf).where( + # Project.allowed_to_condition( + # User.current, :view_dmsf_folders)).order('lft').pluck(:name).each do |name| + # @children.push child(name) + project.children.visible.select(:id, :identifier, :name).has_module(:dmsf).where( + Project.allowed_to_condition(User.current, :view_dmsf_folders)).find_each do |p| + @children << child_project(p) + end + # Folders project.dmsf_folders.visible.pluck(:title).each do |title| @children.push child(title) end + # Files project.dmsf_files.visible.pluck(:name).each do |name| @children.push child(name) end