class ElFinder::Connector
Represents ElFinder
connector on Rails side.
Constants
- DEFAULT_OPTIONS
Default options for instances. @see initialize
- VALID_COMMANDS
Valid commands to run. @see
run
Public Class Methods
new(options)
click to toggle source
Initializes new instance. @param [Hash] options Instance options. :url and :root options are required. @option options [String] :url Entry point of ElFinder
router. @option options [String] :root Root directory of ElFinder
directory structure. @see DEFAULT_OPTIONS
# File lib/el_finder/connector.rb, line 43 def initialize(options) @options = DEFAULT_OPTIONS.merge(options) raise(ArgumentError, "Missing required :url option") unless @options.key?(:url) raise(ArgumentError, "Missing required :root option") unless @options.key?(:root) raise(ArgumentError, "Mime Handler is invalid") unless mime_handler.respond_to?(:for) raise(ArgumentError, "Image Handler is invalid") unless image_handler.nil? || ([:size, :resize, :thumbnail].all?{|m| image_handler.respond_to?(m)}) @root = ElFinder::Pathname.new(options[:root]) @headers = {} @response = {} end
Public Instance Methods
from_hash(hash)
click to toggle source
# File lib/el_finder/connector.rb, line 98 def from_hash(hash) # restore missing '=' len = hash.length % 4 hash += '==' if len == 1 or len == 2 hash += '=' if len == 3 decoded_hash = Base64.urlsafe_decode64(hash) decoded_hash = decoded_hash.respond_to?(:force_encoding) ? decoded_hash.force_encoding('utf-8') : decoded_hash pathname = @root + decoded_hash rescue ArgumentError => e if e.message != 'invalid base64' raise end nil end
options=(value = {})
click to toggle source
@!attribute [w] options Options setter. @param value [Hash] Options to be merged with instance ones. @return [Hash] Updated options.
# File lib/el_finder/connector.rb, line 118 def options=(value = {}) value.each_pair do |k, v| @options[k.to_sym] = v end @options end
run(params)
click to toggle source
Runs request-response cycle. @param [Hash] params Request parameters. :cmd option is required. @option params [String] :cmd Command to be performed. @see VALID_COMMANDS
# File lib/el_finder/connector.rb, line 61 def run(params) @params = params.dup @headers = {} @response = {} @response[:errorData] = {} if VALID_COMMANDS.include?(@params[:cmd]) if @options[:thumbs] @thumb_directory = @root + @options[:thumbs_directory] @thumb_directory.mkdir unless @thumb_directory.exist? raise(RuntimeError, "Unable to create thumbs directory") unless @thumb_directory.directory? end @current = @params[:current] ? from_hash(@params[:current]) : nil @target = (@params[:target] and !@params[:target].empty?) ? from_hash(@params[:target]) : nil if params[:targets] @targets = @params[:targets].map{|t| from_hash(t)} end send("_#{@params[:cmd]}") else invalid_request end @response.delete(:errorData) if @response[:errorData].empty? return @headers, @response end
to_hash(pathname)
click to toggle source
# File lib/el_finder/connector.rb, line 92 def to_hash(pathname) # note that '=' are removed Base64.urlsafe_encode64(pathname.path.to_s).chomp.tr("=\n", "") end
Protected Instance Methods
_archive()
click to toggle source
# File lib/el_finder/connector.rb, line 375 def _archive @response[:error] = 'Invalid Parameters' and return unless !@targets.nil? && @targets.all?{|e| e && e.exist?} && @current && @current.directory? @response[:error] = 'Access Denied' and return unless !@targets.nil? && @targets.all?{|e| perms_for(e)[:read]} && perms_for(@current)[:write] == true @response[:error] = 'No archiver available for this file type' and return if (archiver = @options[:archivers][@params[:type]]).nil? extension = archiver.shift basename = @params[:name] || @targets.first.basename_sans_extension archive = (@root + "#{basename}#{extension}").unique cmd = ['cd', @current.to_s.shellescape, '&&', archiver.map(&:shellescape), archive.to_s.shellescape, @targets.map{|t| t.basename.to_s.shellescape}].flatten.join(' ') if system(cmd) @response[:select] = [to_hash(archive)] _open(@current) else @response[:error] = 'Unable to create archive' end end
_duplicate()
click to toggle source
# File lib/el_finder/connector.rb, line 318 def _duplicate if perms_for(@target)[:read] == false @response[:error] = 'Access Denied' @response[:errorData][@target.basename.to_s] = 'Unable to read' return end if perms_for(@target.dirname)[:write] == false @response[:error] = 'Access Denied' @response[:errorData][@target.dirname.to_s] = 'Unable to write' return end duplicate = @target.duplicate if @target.directory? FileUtils.cp_r(@target, duplicate.fullpath) else FileUtils.copy(@target, duplicate.fullpath) end @response[:select] = [to_hash(duplicate)] _open(@current) end
_edit()
click to toggle source
# File lib/el_finder/connector.rb, line 350 def _edit perms = perms_for(@target) if perms[:read] == true && perms[:write] == true @target.open('w') { |f| f.write @params[:content] } @response[:file] = cdc_for(@target) else @response[:error] = 'Access Denied' end end
_extract()
click to toggle source
# File lib/el_finder/connector.rb, line 361 def _extract @response[:error] = 'Invalid Parameters' and return if @target.nil? || @current.nil? || !(@target.file? && @current.directory?) @response[:error] = 'Access Denied' and return unless perms_for(@target)[:read] == true && perms_for(@current)[:write] == true @response[:error] = 'No extractor available for this file type' and return if (extractor = @options[:extractors][mime_handler.for(@target)]).nil? cmd = ['cd', @current.to_s.shellescape, '&&', extractor.map(&:shellescape), @target.basename.to_s.shellescape].flatten.join(' ') if system(cmd) @params[:tree] = true _open(@current) else @response[:error] = 'Unable to extract files from archive' end end
_mkdir()
click to toggle source
# File lib/el_finder/connector.rb, line 177 def _mkdir if perms_for(@current)[:write] == false @response[:error] = 'Access Denied' return end dir = @current + @params[:name] if !dir.exist? && dir.mkdir @params[:tree] = true @response[:select] = [to_hash(dir)] _open(@current) else @response[:error] = "Unable to create folder" end end
_mkfile()
click to toggle source
# File lib/el_finder/connector.rb, line 194 def _mkfile if perms_for(@current)[:write] == false @response[:error] = 'Access Denied' return end file = @current + @params[:name] if !file.exist? && file.touch @response[:select] = [to_hash(file)] _open(@current) else @response[:error] = "Unable to create file" end end
_open(target = nil)
click to toggle source
# File lib/el_finder/connector.rb, line 129 def _open(target = nil) target ||= @target if target.nil? _open(@root) return end if perms_for(target)[:read] == false @response[:error] = 'Access Denied' return end if target.file? command_not_implemented elsif target.directory? @response[:cwd] = cwd_for(target) @response[:cdc] = target.children. reject{ |child| perms_for(child)[:hidden]}. sort_by{|e| e.basename.to_s.downcase}.map{|e| cdc_for(e)}.compact if @params[:tree] @response[:tree] = { :name => @options[:home], :hash => to_hash(@root), :dirs => tree_for(@root), }.merge(perms_for(@root)) end if @params[:init] @response[:disabled] = @options[:disabled_commands] @response[:params] = { :dotFiles => @options[:allow_dot_files], :uplMaxSize => @options[:upload_max_size], :archives => @options[:archivers].keys, :extract => @options[:extractors].keys, :url => @options[:url] } end else @response[:error] = "Directory does not exist" _open(@root) if File.directory?(@root) end end
_paste()
click to toggle source
# File lib/el_finder/connector.rb, line 271 def _paste if perms_for(from_hash(@params[:dst]))[:write] == false @response[:error] = 'Access Denied' return end @targets.to_a.each do |src| if perms_for(src)[:read] == false || (@params[:cut].to_i > 0 && perms_for(src)[:rm] == false) @response[:error] ||= 'Some files were not copied.' @response[:errorData][src.basename.to_s] = "Access Denied" return else dst = from_hash(@params[:dst]) + src.basename if dst.exist? @response[:error] ||= 'Some files were unable to be copied' @response[:errorData][src.basename.to_s] = "already exists in '#{dst.dirname}'" else if @params[:cut].to_i > 0 src.rename(dst) else if src.directory? FileUtils.cp_r(src.fullpath, dst.fullpath) else FileUtils.cp(src.fullpath, dst.fullpath) end end end end end @params[:tree] = true _open(@current) end
_ping()
click to toggle source
# File lib/el_finder/connector.rb, line 266 def _ping @headers['Connection'] = 'Close' end
_read()
click to toggle source
# File lib/el_finder/connector.rb, line 341 def _read if perms_for(@target)[:read] == true @response[:content] = @target.read else @response[:error] = 'Access Denied' end end
_rename()
click to toggle source
# File lib/el_finder/connector.rb, line 210 def _rename to = @current + @params[:name] perms_for_target = perms_for(@target) if perms_for_target[:rm] == false @response[:error] = 'Access Denied' return end perms_for_current = perms_for(@current) if perms_for_current[:write] == false @response[:error] = 'Access Denied' return end if to.exist? @response[:error] = "Unable to rename #{@target.ftype}. '#{to.basename}' already exists" elsif @target.rename(to) @params[:tree] = to.directory? @response[:select] = [to_hash(to)] _open(@current) else @response[:error] = "Unable to rename #{@target.ftype}" end end
_resize()
click to toggle source
# File lib/el_finder/connector.rb, line 416 def _resize if image_handler.nil? command_not_implemented else if @target.file? perms = perms_for(@target) if perms[:read] == true && perms[:write] == true image_handler.resize(@target, :width => @params[:width].to_i, :height => @params[:height].to_i) @response[:select] = [to_hash(@target)] _open(@current) else @response[:error] = 'Access Denied' end else @response[:error] = "Unable to resize file. It does not exist" end end end
_rm()
click to toggle source
# File lib/el_finder/connector.rb, line 305 def _rm if @targets.empty? @response[:error] = "No files were selected for removal" else @targets.to_a.each do |target| remove_target(target) end @params[:tree] = true _open(@current) end end
_tmb()
click to toggle source
# File lib/el_finder/connector.rb, line 392 def _tmb if image_handler.nil? command_not_implemented else @response[:current] = to_hash(@current) @response[:images] = {} idx = 0 @current.children.select{|e| mime_handler.for(e) =~ /image/}.each do |img| if idx >= @options[:thumbs_at_once] @response[:tmb] = true break end thumbnail = thumbnail_for(img) unless thumbnail.file? image_handler.thumbnail(img, thumbnail, :width => @options[:thumbs_size].to_i, :height => @options[:thumbs_size].to_i) @response[:images][to_hash(img)] = @options[:url] + '/' + thumbnail.path.to_s idx += 1 end end end end
_upload()
click to toggle source
# File lib/el_finder/connector.rb, line 237 def _upload if perms_for(@current)[:write] == false @response[:error] = 'Access Denied' return end select = [] @params[:upload].to_a.each do |file| if file.respond_to?(:tempfile) the_file = file.tempfile else the_file = file end if upload_max_size_in_bytes > 0 && File.size(the_file.path) > upload_max_size_in_bytes @response[:error] ||= "Some files were not uploaded" @response[:errorData][@options[:original_filename_method].call(file)] = 'File exceeds the maximum allowed filesize' else dst = @current + @options[:original_filename_method].call(file) the_file.close src = the_file.path FileUtils.mv(src, dst.fullpath) FileUtils.chmod @options[:upload_file_mode], dst select << to_hash(dst) end end @response[:select] = select unless select.empty? _open(@current) end
Private Instance Methods
cdc_for(pathname)
click to toggle source
# File lib/el_finder/connector.rb, line 505 def cdc_for(pathname) return nil if @options[:thumbs] && pathname.to_s == @thumb_directory.to_s response = { :name => pathname.basename.to_s, :hash => to_hash(pathname), :date => pathname.mtime.to_s, } response.merge! perms_for(pathname) if pathname.directory? response.merge!( :size => 0, :mime => 'directory' ) elsif pathname.file? response.merge!( :size => pathname.size, :mime => mime_handler.for(pathname), :url => (@options[:url] + '/' + pathname.path.to_s) ) if pathname.readable? && response[:mime] =~ /image/ && !image_handler.nil? response.merge!( :resize => true, :dim => image_handler.size(pathname) ) if @options[:thumbs] if (thumbnail = thumbnail_for(pathname)).exist? response.merge!( :tmb => (@options[:url] + '/' + thumbnail.path.to_s)) else @response[:tmb] = true end end end end if pathname.symlink? response.merge!( :link => to_hash(@root + pathname.readlink), # hash of file to which point link :linkTo => (@root + pathname.readlink).relative_to(pathname.dirname.path).to_s, # relative path to :parent => to_hash((@root + pathname.readlink).dirname) # hash of directory in which is linked file ) end return response end
command_not_implemented()
click to toggle source
# File lib/el_finder/connector.rb, line 609 def command_not_implemented @response[:error] = "Command '#{@params[:cmd]}' not yet implemented" end
cwd_for(pathname)
click to toggle source
# File lib/el_finder/connector.rb, line 494 def cwd_for(pathname) { :name => pathname.basename.to_s, :hash => to_hash(pathname), :mime => 'directory', :rel => pathname.is_root? ? @options[:home] : (@options[:home] + '/' + pathname.path.to_s), :size => 0, :date => pathname.mtime.to_s, }.merge(perms_for(pathname)) end
image_handler()
click to toggle source
# File lib/el_finder/connector.rb, line 489 def image_handler @options[:image_handler] end
invalid_request()
click to toggle source
# File lib/el_finder/connector.rb, line 604 def invalid_request @response[:error] = "Invalid command '#{@params[:cmd]}'" end
mime_handler()
click to toggle source
# File lib/el_finder/connector.rb, line 484 def mime_handler @options[:mime_handler] end
perms_for(pathname, options = {})
click to toggle source
# File lib/el_finder/connector.rb, line 569 def perms_for(pathname, options = {}) skip = [options[:skip]].flatten response = {} response[:read] = pathname.readable? if pathname.exist? response[:read] &&= specific_perm_for(pathname, :read) response[:read] &&= @options[:default_perms][:read] response[:write] = pathname.writable? if pathname.exist? response[:write] &&= specific_perm_for(pathname, :write) response[:write] &&= @options[:default_perms][:write] response[:rm] = !pathname.is_root? response[:rm] &&= specific_perm_for(pathname, :rm) response[:rm] &&= @options[:default_perms][:rm] response[:hidden] = false response[:hidden] ||= specific_perm_for(pathname, :hidden) response[:hidden] ||= @options[:default_perms][:hidden] response end
remove_target(target)
click to toggle source
# File lib/el_finder/connector.rb, line 462 def remove_target(target) if target.directory? target.children.each do |child| remove_target(child) end end if perms_for(target)[:rm] == false @response[:error] ||= 'Some files/directories were unable to be removed' @response[:errorData][target.basename.to_s] = "Access Denied" else begin target.unlink if @options[:thumbs] && (thumbnail = thumbnail_for(target)).file? thumbnail.unlink end rescue @response[:error] ||= 'Some files/directories were unable to be removed' @response[:errorData][target.basename.to_s] = "Remove failed" end end end
specific_perm_for(pathname, perm)
click to toggle source
# File lib/el_finder/connector.rb, line 593 def specific_perm_for(pathname, perm) pathname = pathname.path if pathname.is_a?(ElFinder::Pathname) matches = @options[:perms].select{ |k,v| pathname.to_s.send((k.is_a?(String) ? :== : :match), k) } if perm == :hidden matches.one?{|e| e.last[perm] } else matches.none?{|e| e.last[perm] == false} end end
thumbnail_for(pathname)
click to toggle source
# File lib/el_finder/connector.rb, line 457 def thumbnail_for(pathname) @thumb_directory + "#{to_hash(pathname)}.png" end
tree_for(root)
click to toggle source
# File lib/el_finder/connector.rb, line 554 def tree_for(root) root.child_directories(@options[:tree_sub_folders]). reject{ |child| ( @options[:thumbs] && child.to_s == @thumb_directory.to_s ) || perms_for(child)[:hidden] }. sort_by{|e| e.basename.to_s.downcase}. map { |child| {:name => child.basename.to_s, :hash => to_hash(child), :dirs => tree_for(child), }.merge(perms_for(child)) } end
upload_max_size_in_bytes()
click to toggle source
# File lib/el_finder/connector.rb, line 439 def upload_max_size_in_bytes bytes = @options[:upload_max_size] if bytes.is_a?(String) && bytes.strip =~ /(\d+)([KMG]?)/ bytes = $1.to_i unit = $2 case unit when 'K' bytes *= 1024 when 'M' bytes *= 1024 * 1024 when 'G' bytes *= 1024 * 1024 * 1024 end end bytes.to_i end