diff --git a/app/models/dmsf_file_revision.rb b/app/models/dmsf_file_revision.rb
index bbc63bb9..caee38b3 100644
--- a/app/models/dmsf_file_revision.rb
+++ b/app/models/dmsf_file_revision.rb
@@ -25,8 +25,8 @@ class DmsfFileRevision < ActiveRecord::Base
belongs_to :deleted_by_user, :class_name => "User", :foreign_key => "deleted_by_user_id"
belongs_to :project
- acts_as_customizable
-
+ acts_as_customizable
+
acts_as_event :title => Proc.new {|o| "#{l(:label_dmsf_updated)}: #{o.file.dmsf_path_str}"},
:url => Proc.new {|o| {:controller => 'dmsf_files', :action => 'show', :id => o.file}},
:datetime => Proc.new {|o| o.updated_at },
@@ -79,9 +79,9 @@ class DmsfFileRevision < ActiveRecord::Base
["disk_filename = :filename", {:filename => self.disk_filename}])
File.delete(self.disk_file) if dependent.length <= 1 && File.exist?(self.disk_file)
DmsfFileRevisionAccess.find(:all, :conditions => ["dmsf_file_revision_id = ?", self.id]).each {|a| a.destroy}
- CustomValue.find(:all, :conditions => "customized_id = " + self.id.to_s).each do |v|
- v.destroy
- end
+ CustomValue.find(:all, :conditions => "customized_id = " + self.id.to_s).each do |v|
+ v.destroy
+ end
self.destroy
else
self.deleted = true
@@ -134,8 +134,8 @@ class DmsfFileRevision < ActiveRecord::Base
new_revision.name = self.name
new_revision.folder = self.folder
- new_revision.custom_values = self.custom_values.map(&:clone)
-
+ new_revision.custom_values = self.custom_values.map(&:clone)
+
return new_revision
end
@@ -209,20 +209,20 @@ class DmsfFileRevision < ActiveRecord::Base
end
end
end
-
- # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
- def available_custom_fields
- search_project = nil
- if self.project.present?
- search_project = self.project
- elsif self.project_id.present?
- search_project = Project.find(self.project_id)
- end
- if search_project
- search_project.all_dmsf_custom_fields
- else
- DmsfFileRevisionCustomField.all
- end
- end
-end
\ No newline at end of file
+ # Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
+ def available_custom_fields
+ search_project = nil
+ if self.project.present?
+ search_project = self.project
+ elsif self.project_id.present?
+ search_project = Project.find(self.project_id)
+ end
+ if search_project
+ search_project.all_dmsf_custom_fields
+ else
+ DmsfFileRevisionCustomField.all
+ end
+ end
+
+end
diff --git a/lib/redmine_dmsf/webdav/base_resource.rb b/lib/redmine_dmsf/webdav/base_resource.rb
index 94a6748c..a8597664 100644
--- a/lib/redmine_dmsf/webdav/base_resource.rb
+++ b/lib/redmine_dmsf/webdav/base_resource.rb
@@ -1,6 +1,9 @@
module RedmineDmsf
module Webdav
class BaseResource < DAV4Rack::Resource
+ include Redmine::I18n
+ include ActionView::Helpers::NumberHelper
+
DIR_FILE = "
| %s | %s | %s | %s |
"
@@ -24,7 +27,15 @@ module RedmineDmsf
@response.body = ""
Confict unless collection?
- entities = children.map{|child| DIR_FILE % [child.public_path.html_safe, child.long_name || child.name, "-", child.special_type || child.content_type, child.last_modified]} * "\n"
+ entities = children.map{|child|
+ DIR_FILE % [
+ child.public_path,
+ child.long_name || child.name,
+ child.collection? ? '-' : number_to_human_size(child.content_length),
+ child.special_type || child.content_type,
+ child.last_modified
+ ]
+ } * "\n"
@response.body << index_page % [ path.empty? ? "/" : path, path.empty? ? "/" : path , entities ]
end
@@ -62,6 +73,12 @@ table { width:100%%; }
end
protected
+ def basename
+ File.basename(path)
+ end
+ def dirname
+ File.dirname(path)
+ end
def Project
return @Project unless @Project.nil?
pinfo = @path.split('/').drop(1)
@@ -72,6 +89,9 @@ table { width:100%%; }
end
end
end
+ def projectless_path
+ '/'+path.split('/').drop(2).join('/')
+ end
end
end
end
diff --git a/lib/redmine_dmsf/webdav/dmsf_resource.rb b/lib/redmine_dmsf/webdav/dmsf_resource.rb
new file mode 100644
index 00000000..1040293c
--- /dev/null
+++ b/lib/redmine_dmsf/webdav/dmsf_resource.rb
@@ -0,0 +1,132 @@
+module RedmineDmsf
+ module Webdav
+ class DmsfResource < BaseResource
+
+ def children
+ NotFound unless exist? && folder?
+ return @children unless @children.nil?
+ @children = []
+ @_folderdata.subfolders.map do |p|
+ @children.push child(p.title, p)
+ end
+ @_folderdata.files.map do |p|
+ @children.push child(p.name, p)
+ end
+ @children
+
+ end
+
+ def exist?
+ folder? || file?
+ end
+
+ def collection?
+ exist? && folder?
+ end
+
+ def folder?
+ return @_folder unless @_folder.nil?
+ @_folder = false
+ folders = DmsfFolder.find(:all, :conditions => ["project_id = :project_id", {:project_id => self.Project.id}], :order => "title ASC")
+ folders.delete_if {|x| x.title != basename}
+ return false unless folders.length > 0
+ if (folders.length > 1) then
+ folders.delete_if {|x| x.dmsf_path_str != projectless_path}
+ return false unless folders.length > 0
+ @_folder=true
+ @_folderdata = folders[0]
+ else
+ if ('/'+folders[0].dmsf_path_str == projectless_path) then
+ @_folder=true
+ @_folderdata = folders[0]
+ else
+ @_folder= false
+ end
+ end
+ @_folder
+ end
+
+ def file?
+ return @_file unless @_file.nil?
+ @_file = false
+ files = DmsfFile.find(:all, :conditions => ["project_id = :project_id AND name = :file_name AND deleted = :deleted", {:project_id => self.Project.id, :file_name => basename, :deleted => false}], :order => "name ASC")
+ files.delete_if {|x| File.dirname('/'+x.dmsf_path_str) != File.dirname(projectless_path)}
+ if files.length > 0
+ @_filedata = files[0]
+ @_file = true
+ end
+ end
+
+ def content_type
+ if folder? then
+ "inode/directory"
+ elsif file?
+ @_filedata.last_revision.detect_content_type
+ else
+ NotFound
+ end
+ end
+
+ def creation_date
+ if folder?
+ @_folderdata.created_at
+ elsif file?
+ @_filedata.created_at
+ else
+ NotFound
+ end
+ end
+
+ def last_modified
+ if folder?
+ @_folderdata.updated_at
+ elsif file?
+ @_filedata.updated_at
+ else
+ NotFound
+ end
+ end
+
+ def etag
+ filesize = file? ? @_filedata.size : 4096;
+ fileino = file? ? File.stat(@_filedata.last_revision.disk_file).ino : 2;
+ sprintf('%x-%x-%x', fileino, filesize, last_modified.to_i)
+ end
+
+ def content_length
+ file? ? @_filedata.size : 4096;
+ end
+
+ def special_type
+ l(:field_folder) if folder?
+ end
+
+ def get(request, response)
+ raise NotFound unless exist?
+ if collection?
+ html_display
+ response['Content-Length'] = response.body.bytesize.to_s
+ else
+ response.body = download
+ end
+ OK
+ end
+
+ protected
+ def download
+ raise NotFound unless file?
+ #log_activity("downloaded")
+ if @request.env['HTTP_RANGE'].nil?
+ access = DmsfFileRevisionAccess.new(:user_id => User.current.id, :dmsf_file_revision_id => @_filedata.last_revision.id,
+ :action => DmsfFileRevisionAccess::DownloadAction)
+ access.save!
+ end
+
+ Download.new(@_filedata.last_revision.disk_file)
+
+ end
+ end
+ end
+end
+
+
diff --git a/lib/redmine_dmsf/webdav/download.rb b/lib/redmine_dmsf/webdav/download.rb
new file mode 100644
index 00000000..0dcaec0b
--- /dev/null
+++ b/lib/redmine_dmsf/webdav/download.rb
@@ -0,0 +1,32 @@
+require 'time'
+require 'rack/utils'
+require 'rack/mime'
+
+module RedmineDmsf
+ module Webdav
+ class Download < Rack::File
+ def initialize(root, cache_control = nil)
+ @path = root
+ @cache_control = cache_control
+ end
+
+ def _call(env)
+ unless ALLOWED_VERBS.include? env["REQUEST_METHOD"]
+ return fail(405, "Method Not Allowed")
+ end
+
+ available = begin
+ F.file?(@path) && F.readable?(@path)
+ rescue SystemCallError
+ false
+ end
+
+ if available
+ serving(env)
+ else
+ raise NotFound
+ end
+ end
+ end
+ end
+end
diff --git a/lib/redmine_dmsf/webdav/project_resource.rb b/lib/redmine_dmsf/webdav/project_resource.rb
index 440fc514..6025a387 100644
--- a/lib/redmine_dmsf/webdav/project_resource.rb
+++ b/lib/redmine_dmsf/webdav/project_resource.rb
@@ -9,21 +9,18 @@ module RedmineDmsf
def children
#caching for repeat usage
return @children unless @children.nil?
+ @children = []
DmsfFolder.project_root_folders(self.Project).map do |p|
- child p.title, p
+ @children.push child(p.title, p)
end
DmsfFile.project_root_files(self.Project).map do |p|
- child p.display_name, p
+ @children.push child(p.name, p)
end
- end
-
-
- def name
- self.Project.name unless self.Project.nil?
+ @children
end
def exist?
- !self.Project.nil?
+ !(self.Project.nil? || User.current.anonymous?)
end
def collection?
@@ -55,7 +52,7 @@ module RedmineDmsf
end
def special_type
- "Project"
+ l(:field_project)
end
def content_length