file-manager/app/models/file_manager_setting.rb

287 lines
10 KiB
Ruby

class FileManagerSetting
include Mongoid::Document
include Mongoid::Timestamps
field :only_editable_for_uploader, type: Boolean, default: false
field :root_path, type: String, default: ""
field :modules_saved_info, type: Hash, default: {}
field :modules_keys, type: Array, default: []
belongs_to :file_manager_root
has_many :file_manager_uploads
has_many :file_manager_trashes
@@mutex = Mutex.new
@@resource = ConditionVariable.new
def self.get_models_uploaders
if !self.class_variable_defined?(:@@get_models_uploaders)
@@get_models_uploaders = false
end
if @@get_models_uploaders
@@mutex.synchronize {
@@resource.wait(@@mutex)
}
end
@@get_models_uploaders = true
if self.class_variable_defined?(:@@modules_info)
@@get_models_uploaders = false
return @@modules_info
end
setting = self.first
if setting.nil?
setting = self.create
end
modules_info = {}
file_only_models = []
user_id_fields = ['user_id', 'create_user_id', 'update_user_id']
user_id_field_info = {}
Rails::Engine.descendants.each do |engine|
unless engine.abstract_railtie? || engine.initializers.blank?
module_name = engine.initializers[0].name
if ModuleApp.where(:key=> module_name).count > 0
models_path = Dir.glob("#{engine.root}/app/models/*")
uploaders = {}
models_path.each do |path|
begin
require File.basename(path)
m = File.basename(path).sub(/\..+/, '').camelize.constantize
if m.uploaders.count > 0
user_id_field = nil
user_id_fields.each do |f|
if m.fields.include?(f)
user_id_field = f
break
end
end
if user_id_field.nil?
user_id_field = m.fields.select{|f| f.include?('user_id')}.first
end
user_id_field_info[m] = user_id_field
uploaders_info = {}
obj = m.new(:id=>nil)
m.uploaders.each do |field, uploader_klass|
uploaders_info[field] = {
uploader_klass => "public/" + obj.send(field).store_dir
}
end
self.set_record_callback(setting, module_name, m, user_id_field)
uploaders[m] = uploaders_info
m_str = m.to_s
if m_str.match(/(File|Image)$/)
file_only_models << m_str
else
belongs_to_fields = m.relations.select{|k,v| v.macro == :belongs_to}.keys
if belongs_to_fields.count > 0 && (m.relations.count - belongs_to_fields.count) == 0
fields = m.fields.keys - belongs_to_fields.map{|s| "#{s}_id"}
fields = fields - ["_id", "created_at", "updated_at", "description", "title", "title_translations", "rss2_id", "order", "choose_lang", "privacy_type", "should_destroy", "file_title", "download_count", "sort_number"]
if (fields - m.uploaders.keys.map(&:to_s)).count == 0
file_only_models << m_str
end
end
end
end
rescue LoadError
end
end
if uploaders.count > 0
modules_info[module_name] = uploaders
end
end
end
end
begin
require 'asset'
module_name = 'asset'
m = Asset
uploaders = {}
if m.uploaders.count > 0
uploaders_info = {}
obj = m.new(:id=>nil)
m.uploaders.each do |field, uploader_klass|
uploaders_info[field] = {
uploader_klass => "public/" + obj.send(field).store_dir
}
end
uploaders[m] = uploaders_info
user_id_field = nil
user_id_fields.each do |f|
if m.fields.include?(f)
user_id_field = f
break
end
end
if user_id_field.nil?
user_id_field = m.fields.select{|f| f.include?('user_id')}.first
end
user_id_field_info[m] = user_id_field
self.set_record_callback(setting, module_name, m, user_id_field)
user_id_field
end
modules_info[module_name] = uploaders
file_only_models << m.to_s
rescue LoadError
end
@@file_only_models = file_only_models
@@user_id_field_info = user_id_field_info
@@modules_info = modules_info
@@mutex.synchronize {
@@get_models_uploaders = false
@@resource.signal
}
modules_info
end
def self.set_record_callback(setting, module_name, m, user_id_field)
uploader_fields = m.uploaders.keys
m_str = m.to_s
m.before_save do |record|
uploader_fields.each{|f| record.instance_variable_set("@#{f}_changed", record.send("#{f}_changed?"))}
true
end
m.after_save do |record|
uploader_fields.each do |f|
f_changed = "@#{f}_changed"
if record.instance_variable_get(f_changed)
store_path = "public#{URI.decode(record.send(f).url)}"
if user_id_field
user_id = record.send(user_id_field)
else
user_id = nil
end
basic_info = {:module=> module_name, :model=>m_str, :related_field=> f, :related_id => record.id}
other_info = {:path=> store_path, :user_id=> user_id, :is_default=>true, :created_at => record.created_at, :updated_at => record.updated_at}
full_info = other_info.merge(basic_info)
old_record = setting.file_manager_uploads.where(basic_info).first
if old_record.nil?
setting.file_manager_uploads.create(full_info)
else
old_record.update_attributes(other_info)
end
end
record.remove_instance_variable(f_changed) unless record.instance_variable_get(f_changed).nil?
end
true
end
m.after_destroy do |record|
unless record.instance_variable_get(:@skip_remove_callback)
setting.file_manager_uploads.where(:model=>m_str, :related_id => record.id).destroy
end
true
end
end
def self.file_only_models
unless self.class_variable_defined?(:@@file_only_models)
self.get_models_uploaders
end
return @@file_only_models
end
def self.get_module_info(key)
if key == 'all'
title = I18n.t("file_manager.all_files")
link = nil
icon_class = 'icons-disk'
sidebar = nil
elsif key == 'asset'
title = I18n.t('filemanager')
link = Rails.application.routes.url_helpers.admin_assets_path
icon_class = 'icons-folder'
sidebar = nil
else
module_app = ModuleApp.where(:key=>key).first
return if module_app.nil?
t = module_app.get_registration
return if t.nil?
sidebar = t.get_side_bar
if sidebar
t = sidebar
icon_class = t.get_icon_class
module_label = t.instance_variable_get(:@head_label)
link = t.instance_variable_get(:@head_link)
if link
link = Rails.application.routes.url_helpers.send(link)
end
else
icon_class = module_app.icon_class_no_sidebar
module_label = t.instance_variable_get(:@module_label)
plugin_t = OrbitApp::Plugin::Registration.find_by_module_app_name(module_app.title)
link = plugin_t.admin_partial_path if plugin_t
end
title = I18n.t(module_label)
end
{
:title => title,
:link => link,
:icon_class => icon_class,
:sidebar => sidebar
}
end
def create_records
modules_info = self.class.get_models_uploaders
models_dict = self.modules_saved_info
modules_info.each do |module_key, uploaders|
uploaders.each do |m, uploaders_info|
m_str = m.to_s
if models_dict[m_str].nil?
models_dict[m_str] = nil
end
end
end
self.modules_saved_info = models_dict
self.modules_keys = modules_info.keys
self.save
if self.class.all.count > 1
self.class.where(:id.ne=> self.id).destroy
end
modules_info.each do |module_key, uploaders|
# module_app = ModuleApp.where(:key=> module_key).first
# I18n.t("module_name.#{module_key}")
uploaders.each do |m, uploaders_info|
user_id_field = @@user_id_field_info[m]
uploader_fields = uploaders_info.keys
records = m.any_of(uploader_fields.map{|f| {f => {"$ne" => nil}}})
m_str = m.to_s
if self.modules_saved_info[m_str]
records = records.where(:created_at.gte=> (self.modules_saved_info[m_str] - 1))
end
records = records.order_by(:created_at=> :asc).to_a
records_last_idx = records.length - 1
records.each_with_index do |r, i|
uploader_fields.each do |f|
f_value = r.send(f)
if f_value.present?
store_path = "public#{URI.decode(f_value.url)}"
unless File.exist?(store_path)
next
end
if user_id_field
user_id = r.send(user_id_field)
else
user_id = nil
end
basic_info = {:module=> module_key, :model=> m.to_s, :related_field=> f, :related_id => r.id, :is_default=> true}
other_info = {:path=> store_path, :user_id=> user_id, :created_at => r.created_at, :updated_at => r.updated_at}
full_info = other_info.merge(basic_info)
old_record = self.file_manager_uploads.where(basic_info).first
if old_record.nil?
self.file_manager_uploads.create(full_info)
else
old_record.update_attributes(other_info)
end
end
end
if i % 10 || i == records_last_idx
puts "#{m} updated at #{r.created_at}"
self.class.where(:id=>self.id).update_all("modules_saved_info.#{m}" => r.created_at.to_i)
end
end
end
end
end
def get_modules_keys
_modules_keys = self.modules_keys.sort
_modules_keys = ["all"] + ["asset"] + (_modules_keys - ["asset"])
end
end