class CamaleonCmsLocalUploader < CamaleonCmsUploader def after_initialize @root_folder = @current_site.upload_directory FileUtils.mkdir_p(@root_folder) unless Dir.exist?(@root_folder) end def setup_private_folder @root_folder = Rails.root.join(self.class::PRIVATE_DIRECTORY).to_s FileUtils.mkdir_p(@root_folder) unless Dir.exist?(@root_folder) end def browser_files(prefix = '/', _objects = {}) path = File.join(@root_folder, prefix) Dir.entries(path).each do |f_name| next if ['..', '.', 'thumb'].include?(f_name) obj = file_parse(File.join(path, f_name).sub(@root_folder, '').cama_fix_media_key) cache_item(obj) browser_files(File.join(prefix, obj['name'])) if obj['is_folder'] end end def fetch_file(file_name) return { error: 'Invalid file path' } unless valid_folder_path?(file_name) return file_name if file_exists?(file_name) { error: 'File not found' } end def file_parse(key) file_path = File.join(@root_folder, key) url_path = file_path.sub(Rails.root.join('public').to_s, '') is_dir = File.directory?(file_path) res = { 'name' => File.basename(key), 'folder_path' => File.dirname(key), 'url' => if is_dir '' else (if is_private_uploader? url_path.sub("#{@root_folder}/", '') else File.join( @current_site.decorate.the_url(as_path: true, locale: false, skip_relative_url_root: true), url_path ) end) end, 'is_folder' => is_dir, 'file_size' => is_dir ? 0 : File.size(file_path).round(2), 'thumb' => '', 'file_type' => self.class.get_file_format(file_path), 'dimension' => '' }.with_indifferent_access res['key'] = File.join(res['folder_path'], res['name']) if res['file_type'] == 'image' && File.extname(file_path).downcase != '.gif' res['thumb'] = (is_private_uploader? ? "/admin/media/download_private_file?file=#{version_path(key).slice(1..-1)}" : version_path(res['url'])) end if res['file_type'] == 'image' res['thumb'].sub! '.svg', '.jpg' im = MiniMagick::Image.open(file_path) res['dimension'] = begin "#{im[:width]}x#{im[:height]}" rescue StandardError '0x0' end end res end # save a file into local folder def add_file(uploaded_io_or_file_path, key, args = {}) args = { same_name: false, is_thumb: false }.merge(args) res = nil key = search_new_key(key) unless args[:same_name] if @instance # private hook to upload files by different way, add file data into result_data _args = { result_data: nil, file: uploaded_io_or_file_path, key: key, args: args, klass: self } @instance.hooks_run('uploader_local_before_upload', _args) return _args[:result_data] if _args[:result_data].present? end add_folder(File.dirname(key)) if File.dirname(key).present? upload_io = uploaded_io_or_file_path.is_a?(String) ? File.open(uploaded_io_or_file_path) : uploaded_io_or_file_path File.open(File.join(@root_folder, key), 'wb') { |file| file.write(upload_io.read) } res = cache_item(file_parse(key)) unless args[:is_thumb] res end # create a new folder into local directory def add_folder(key) return { error: 'Invalid folder path' } unless valid_folder_path?(key) d = File.join(@root_folder, key).to_s is_new_folder = false unless Dir.exist?(d) FileUtils.mkdir_p(d) is_new_folder = true if File.basename(d) != 'thumb' end f = file_parse(key) cache_item(f) if is_new_folder f end # remove an existent folder def delete_folder(key) return { error: 'Invalid folder path' } if key.include?('..') folder = File.join(@root_folder, key) FileUtils.rm_rf(folder) if Dir.exist? folder get_media_collection.find_by_key(key).take.destroy end # remove an existent file def delete_file(key) return { error: 'Invalid file path' } if key.include?('..') file = File.join(@root_folder, key) FileUtils.rm(file) if File.exist? file @instance.hooks_run('after_delete', key) get_media_collection.find_by_key(key).take.destroy end # convert a real file path into file key def parse_key(file_path) file_path.sub(@root_folder, '').cama_fix_media_key end end