172 lines
6.2 KiB
Ruby
172 lines
6.2 KiB
Ruby
class FileManagerUpload
|
|
include Mongoid::Document
|
|
include Mongoid::Timestamps
|
|
Restrict_dirs = ["/", "/home/", "/etc/", "/var/*/", "/root/", "/usr/*/"]
|
|
field :module, type: String, default: ""
|
|
field :model, type: String, default: ""
|
|
field :related_field, type: String, default: ""
|
|
field :related_id, type: BSON::ObjectId
|
|
field :is_file, type: Boolean, default: true
|
|
field :filename, type: String, default: ""
|
|
field :path, type: String, default: ""
|
|
field :version, type: Integer, default: 1
|
|
field :is_default, type: Boolean, default: false
|
|
field :user_id
|
|
field :is_trash, type: Boolean, default: false
|
|
belongs_to :file_manager_setting
|
|
has_one :file_manager_trash
|
|
index({model: 1, related_field: 1, related_id: 1}, { unique: false, background: true })
|
|
index({module: 1}, { unique: false, background: true })
|
|
index({version: -1}, { unique: false, background: true })
|
|
index({created_at: -1}, { unique: false, background: true })
|
|
index({path: 1}, { unique: false, background: true })
|
|
index({filename: 1}, { unique: false, background: true })
|
|
index({is_trash: 1}, { unique: false, background: true })
|
|
|
|
before_save do
|
|
self.filename = File.basename(self.path)
|
|
if self.filename_changed? && self.related_id.present?
|
|
m = self.model.constantize
|
|
info = {self.related_field => self.filename}
|
|
if self.model == 'Asset'
|
|
I18n.available_locales.each do |l|
|
|
info["title.#{l}"] = self.filename
|
|
end
|
|
end
|
|
m.where(:id=> self.related_id).update_all(info)
|
|
end
|
|
true
|
|
end
|
|
|
|
def self.check_restricted(path)
|
|
return Restrict_dirs.map{|d| path.match("^#{d.gsub('/*/','/.*')}[^/]+(/|)$")}.compact.length > 0
|
|
end
|
|
|
|
def get_related
|
|
begin
|
|
m = self.model.constantize
|
|
related = m.where(:id=> self.related_id).first
|
|
rescue => e
|
|
related = nil
|
|
puts "get_related: #{e}"
|
|
end
|
|
related
|
|
end
|
|
|
|
def generate_new_upload
|
|
clone_record = self.clone
|
|
clone_record.is_trash = false
|
|
clone_record.created_at = Time.now
|
|
clone_record.updated_at = Time.now
|
|
self.update_path(self.path, self.is_default ,true)
|
|
clone_record.version += 1
|
|
clone_record.save
|
|
clone_record
|
|
end
|
|
def delete_file(record_only=false,override_user_id=nil, real_delete=false, is_slave=false, trash_path=nil)
|
|
if !real_delete
|
|
unless self.is_trash
|
|
unless self.is_file
|
|
if !is_slave && Dir.glob(Pathname.new(self.path).join("*").to_s).count == 0 #remove empty dir
|
|
self.delete_file_permanent
|
|
return
|
|
end
|
|
end
|
|
override_user_id = self.user_id if override_user_id.nil?
|
|
unless self.class.check_restricted(self.path)
|
|
setting = self.file_manager_setting
|
|
setting = FileManagerRoot.first if setting.nil?
|
|
self.file_manager_trash = FileManagerTrash.create(:record_only=>record_only,:file_manager_upload=>self,:is_file=>is_file,:user_id=>override_user_id,:module=>self.module,:path=>self.path,:file_manager_setting=>setting,:is_slave=>is_slave, :trash_path=>trash_path)
|
|
self.update(:is_trash => true)
|
|
if record_only
|
|
other_records = self.class.where(:path=>self.path,:id.ne=>self.id,:is_trash=>false).order_by(:version=>-1).to_a
|
|
if other_records.count != 0
|
|
newest_record = other_records[0]
|
|
if self.is_default
|
|
newest_record.update_path(self.path, true)
|
|
end
|
|
newest_record
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
else
|
|
puts "Path: #{path}"
|
|
puts "File or Directory restricted!"
|
|
end
|
|
end
|
|
else
|
|
self.delete_file_permanent
|
|
end
|
|
end
|
|
def delete_file_permanent(only_self=false)
|
|
if only_self
|
|
real_path = self.get_real_path
|
|
FileManagerTrash.delete_file_permanent(real_path, nil, true)
|
|
unless self.is_default
|
|
dir = File.dirname(real_path)
|
|
if Dir.entries(dir).empty?
|
|
FileUtils.rm_rf(dir)
|
|
end
|
|
end
|
|
related = self.get_related
|
|
if self.is_default
|
|
other_records = self.class.where(:file_manager_setting=>self.file_manager_setting,:path=>self.path,:id.ne=>self.id).order_by(:version=>-1)
|
|
if other_records.count != 0
|
|
newest_record = other_records[0]
|
|
real_old_path = newest_record.get_real_path(self.path)
|
|
newest_record.update_path(self.path, true)
|
|
dir = File.dirname(real_old_path)
|
|
if (Dir.entries(dir) - ['.','..']).empty?
|
|
FileUtils.rm_rf(dir)
|
|
end
|
|
self.update(:is_default => false)
|
|
end
|
|
end
|
|
self.destroy
|
|
else
|
|
FileManagerTrash.delete_file_permanent(self.path)
|
|
self.class.where(:file_manager_setting=>self.file_manager_setting,:path=>self.path,:is_trash=>false).destroy
|
|
end
|
|
end
|
|
def get_real_path(tmp_path=self.path, override_default=self.is_default)
|
|
return (override_default ? tmp_path : "#{File.dirname(tmp_path)}/.versions/v#{self.version}/#{File.basename(tmp_path)}#{self.is_file ? '' : '/'}")
|
|
end
|
|
def update_path(new_path, override_default = nil, move_to_old_version=false, copy_mode=false)
|
|
override_default = self.is_default if override_default.nil?
|
|
real_old_path = self.get_real_path(self.path)
|
|
if move_to_old_version
|
|
real_new_path = self.get_real_path(new_path, false)
|
|
self.is_default = false
|
|
else
|
|
self.is_default = override_default
|
|
real_new_path = self.get_real_path(new_path, override_default)
|
|
end
|
|
if File.exist?(real_old_path)
|
|
dir = File.dirname(real_new_path)
|
|
FileUtils.mkdir_p(dir)
|
|
if real_old_path != real_new_path
|
|
FileUtils.mv(real_old_path, real_new_path)
|
|
end
|
|
end
|
|
self.path = new_path
|
|
self.save
|
|
if self.is_default && self.related_id.present?
|
|
m = self.model.constantize
|
|
m.where(:id=>self.related_id).update_all(self.related_field => self.filename)
|
|
end
|
|
self
|
|
end
|
|
|
|
def remove_file_callback
|
|
m = self.model.constantize
|
|
if FileManagerSetting.file_only_models.include?(self.model)
|
|
m.where(:id=>self.related_id).to_a.each do |record|
|
|
record.instance_variable_set(:@skip_remove_callback, true)
|
|
record.destroy
|
|
end
|
|
else
|
|
m.where(:id=>self.related_id).update_all(self.related_field => nil)
|
|
end
|
|
end
|
|
end |