class ElFinderFtp::Connector
Represents ElFinder connector on Rails side.
Constants
- DEFAULT_OPTIONS
Default options for instances. @see initialize
- VALID_COMMANDS
Valid commands to run. @see
run
Attributes
adapter[R]
Public Class Methods
logger()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 60 def logger @logger ||= Logger.new(STDOUT) end
logger=(val)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 63 def logger=(val) @logger = val end
new(options)
click to toggle source
Initializes new instance. @param [Hash] options Instance options. :url and :server options are required. @option options [String] :url Entry point of ElFinder router. @option options [String] :server A hash containing the :host, :username, :password, and, optionally, :port to connect to @see DEFAULT_OPTIONS
# File lib/el_finder_ftp/connector.rb, line 46 def initialize(options) @options = DEFAULT_OPTIONS.merge(options) raise(ArgumentError, "Missing required :url option") unless @options.key?(:url) raise(ArgumentError, "Missing required :server option") unless @options.key?(:server) 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)}) @headers = {} @response = {} end
Public Instance Methods
from_hash(hash)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 121 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_ftp/connector.rb, line 141 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_ftp/connector.rb, line 72 def run(params) @adapter = ElFinderFtp::FtpAdapter.new(@options[:server]) @root = ElFinderFtp::Pathname.new(adapter) begin @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 begin send("_#{@params[:cmd]}") rescue Net::FTPPermError @response[:error] = 'Access Denied' end else invalid_request end @response.delete(:errorData) if @response[:errorData].empty? return @headers, @response ensure adapter.close end end
to_hash(pathname)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 115 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_ftp/connector.rb, line 409 def _archive command_not_implemented end
_duplicate()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 367 def _duplicate command_not_implemented end
_extract()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 404 def _extract command_not_implemented end
_file()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 381 def _file if perms_for(@target)[:read] == true @response[:file_data] = @target.read @response[:mime_type] = mime_handler.for(@target) @response[:disposition] = 'attachment' @response[:filename] = @target.basename.to_s else @response[:error] = 'Access Denied' end end
_get()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 372 def _get if perms_for(@target)[:read] == true @response[:content] = @target.read else @response[:error] = 'Access Denied' end end
_ls()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 196 def _ls if @target.directory? files = @target.files.reject{ |child| perms_for(child)[:hidden] } @response[:list] = files.map{|e| e.basename.to_s }.compact else @response[:error] = "Directory does not exist" end end
_mkdir()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 217 def _mkdir if perms_for(@target)[:write] == false @response[:error] = 'Access Denied' return end unless valid_name?(@params[:name]) @response[:error] = 'Unable to create folder' return end dir = @target + @params[:name] if !dir.exist? && dir.mkdir @response[:added] = [cdc_for(dir)] else @response[:error] = "Unable to create folder" end end
_mkfile()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 236 def _mkfile if perms_for(@target)[:write] == false @response[:error] = 'Access Denied' return end unless valid_name?(@params[:name]) @response[:error] = 'Unable to create file' return end file = @target + @params[:name] if !file.exist? && file.touch @response[:added] = [cdc_for(file)] else @response[:error] = "Unable to create file" end end
_open(target = nil)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 152 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] = cdc_for(target) files = [target].concat( target.files.reject{ |child| perms_for(child)[:hidden] } ) if @params[:tree] files = files.concat( tree_for(@root) ) else files = files.concat( target.child_directories.reject{ |child| perms_for(child)[:hidden] || child.fullpath == target.fullpath } ) end @response[:files] = files.map{|e| cdc_for(e)}.compact if @params[:init] @response[:api] = 2 @response[:uplMaxSize] = @options[:upload_max_size] @response[:options] = { :disabled => @options[:disabled_commands], :dotFiles => @options[:allow_dot_files], :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_ftp/connector.rb, line 317 def _paste if perms_for(from_hash(@params[:dst]))[:write] == false @response[:error] = 'Access Denied' return end added_list = [] removed_list = [] @targets.to_a.each do |src| if perms_for(src)[:read] == false || (@params[:cut].to_i > 0 && perms_for(src)[:locked] == true) @response[:error] ||= 'Some files were not moved.' @response[:errorData][src.basename.to_s] = "Access Denied" return else dst = from_hash(@params[:dst]) + src.basename if dst.exist? @response[:error] ||= 'The target file already exists' @response[:errorData][src.basename.to_s] = "already exists in '#{dst.dirname}'" else if @params[:cut].to_i > 0 adapter.move(src, dst) added_list.push cdc_for(dst) removed_list.push to_hash(src) else command_not_implemented return end end end end @response[:added] = added_list unless added_list.empty? @response[:removed] = removed_list unless removed_list.empty? end
_ping()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 312 def _ping @headers['Connection'] = 'Close' end
_put()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 393 def _put perms = perms_for(@target) if perms[:read] == true && perms[:write] == true @target.write @params[:content] @response[:changed] = [cdc_for(@target)] else @response[:error] = 'Access Denied' end end
_rename()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 255 def _rename unless valid_name?(@params[:name]) @response[:error] = "Unable to rename #{@target.ftype}" return end to = @target.dirname + @params[:name] perms_for_target = perms_for(@target) if perms_for_target[:locked] == true @response[:error] = 'Access Denied' return end perms_for_current = perms_for(@target) 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" else to = @target.rename(to) if to @response[:added] = [cdc_for(to)] @response[:removed] = [to_hash(@target)] else @response[:error] = "Unable to rename #{@target.ftype}" end end end
_resize()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 419 def _resize command_not_implemented end
_rm()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 354 def _rm if @targets.empty? @response[:error] = "No files were selected for removal" else removed_list = [] @targets.to_a.each do |target| removed_list.concat remove_target(target) end @response[:removed] = removed_list unless removed_list.empty? end end
_tmb()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 414 def _tmb command_not_implemented end
_tree()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 207 def _tree if @target.directory? @response[:tree] = tree_for(@target).map{|e| cdc_for(e) }.compact else @response[:error] = "Directory does not exist" end end
_upload()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 289 def _upload if perms_for(@target)[:write] == false @response[:error] = 'Access Denied' return end added_list = [] @params[:upload].to_a.each do |io| name = @options[:original_filename_method].call(io) unless valid_name?(name) @response[:error] = 'Unable to create file' return end dst = @target + name dst.write(io) added_list.push cdc_for(dst) end @response[:added] = added_list unless added_list.empty? _open(@current) end
Private Instance Methods
cdc_for(pathname)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 486 def cdc_for(pathname) return nil if @options[:thumbs] && pathname.to_s == @thumb_directory.to_s response = { :name => pathname.is_root? ? "Home" : pathname.basename.to_s, :hash => to_hash(pathname), :date => pathname.mtime.to_s, :ts => pathname.mtime.to_i } response.merge! perms_for(pathname) response[:phash] = to_hash(pathname.dirname) unless pathname.is_root? if pathname.directory? response.merge!( :size => 0, :mime => 'directory', :dirs => pathname.child_directories.size ) response[:volumeid] = 'Home' if pathname.is_root? 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_ftp/connector.rb, line 613 def command_not_implemented @response[:error] = "Command '#{@params[:cmd]}' not implemented" end
image_handler()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 482 def image_handler @options[:image_handler] end
invalid_request()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 608 def invalid_request @response[:error] = "Invalid command '#{@params[:cmd]}'" end
mime_handler()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 477 def mime_handler @options[:mime_handler] end
perms_for(pathname, options = {})
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 568 def perms_for(pathname, options = {}) skip = [options[:skip]].flatten response = {} response[:read] = pathname.readable? response[:read] &&= specific_perm_for(pathname, :read) response[:read] &&= @options[:default_perms][:read] response[:write] = pathname.writable? response[:write] &&= specific_perm_for(pathname, :write) response[:write] &&= @options[:default_perms][:write] response[:locked] = pathname.is_root? response[:locked] &&= specific_perm_for(pathname, :locked) response[:locked] &&= @options[:default_perms][:locked] 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_ftp/connector.rb, line 450 def remove_target(target) removed = [] if target.directory? target.children.each do |child| removed.concat remove_target(child) end end if perms_for(target)[:locked] == true @response[:error] ||= 'Some files/directories were unable to be removed' @response[:errorData][target.basename.to_s] = "Access Denied" else begin removed.push to_hash(target) target.unlink if @options[:thumbs] && (thumbnail = thumbnail_for(target)).file? removed.push to_hash(thumbnail) thumbnail.unlink end rescue Exception => ex @response[:error] ||= 'Some files/directories were unable to be removed' @response[:errorData][target.basename.to_s] = "Remove failed" end end removed end
specific_perm_for(pathname, perm)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 592 def specific_perm_for(pathname, perm) pathname = pathname.path if pathname.is_a?(ElFinderFtp::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_ftp/connector.rb, line 445 def thumbnail_for(pathname) @thumb_directory + "#{to_hash(pathname)}.png" end
tree_for(root)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 541 def tree_for(root) # root.child_directories. # 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)) # } children = [root] flattened_tree = [] while !children.empty? do child = children.pop unless (@options[:thumbs] && child.to_s == @thumb_directory.to_s ) || perms_for(child)[:hidden] flattened_tree.push child children.concat child.child_directories end end flattened_tree end
upload_max_size_in_bytes()
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 427 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
valid_name?(name)
click to toggle source
# File lib/el_finder_ftp/connector.rb, line 603 def valid_name?(name) @options[:name_validator].call(name) end