class Alchemy::Custom::Model::ElFinder::Connector

Constants

DEFAULT_OPTIONS

Default options for instances. @see initialize

VALID_COMMANDS

Valid commands to run. @see run

VERSION

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/alchemy/custom/model/el_finder/connector.rb, line 37
def initialize(options)
  @options = DEFAULT_OPTIONS.merge(options)

  @options[:disabled_commands] += ['mkdir', 'rename']

  raise(ArgumentError, "Missing required :volumes option") unless @options.key?(:volumes)
  # 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)})

  @volumes = options[:volumes]
  @root = PathName.new(options[:root])

  @headers = {}
  @response = {}
end

Public Instance Methods

from_hash(hash) click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 103
def from_hash(hash)
  volume = @volumes.find {|v| v.contains?(hash)}
  if volume
    [volume, volume.decode(hash)]
  else
    @response[:error] = 'errFileNotFound'
    nil
  end
  # 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/alchemy/custom/model/el_finder/connector.rb, line 132
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/alchemy/custom/model/el_finder/connector.rb, line 61
def run(params)
  @params = params.dup
  @headers = {}
  @response = {}
  @response[:errorData] = {}
  @file = nil

  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
    @volume, @target = (@params[:target] and !@params[:target].empty?) ? from_hash(@params[:target]) : [nil, 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, @file
end
to_hash(pathname) click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 95
def to_hash(pathname)
  # note that '=' are removed
  Base64.urlsafe_encode64(pathname.path.to_s).chomp.tr("=\n", "")
end

Protected Instance Methods

_dim() click to toggle source

of open

# File lib/alchemy/custom/model/el_finder/connector.rb, line 233
def _dim
  if @target.is_a? ElFinder::Paths::Image
    @response[:dim] = @target.dim
  else
    @response[:error] = "Operazione non supportata"
  end
end
_duplicate() click to toggle source

of resize

# File lib/alchemy/custom/model/el_finder/connector.rb, line 347
def _duplicate

  @targets.each do |v, f|
    unless f.is_image?
      @response[:error] = "#{f.name} non è un'immagine"
      return
    end
  end

  @targets.each do |v, f|
    unless v.duplicable?(f)
      @response[:error] = "#{f.name} non può essere duplicato"
      return
    end
  end

  added = @targets.collect do |v, t|
    v.path_info(v.duplicate(t))
  end

  @response[:added] = added
  # _open(@targets.first[0], @targets.first[0].root_path)
end
_file() click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 145
def _file
  if @volume && @target
    path = @volume.pathname(@target)
    @file = {path: path}
  end
end
_ls() click to toggle source

Funzione lanciata praticamente all'upload dei file, dato che non abbiamo problemi di duplicati dato che sono tutti in database, inviamo sempre un vuoto nel caso dobbiamo implementare invece questo: github.com/Studio-42/elFinder/wiki/Client-Server-API-2.1#ls

# File lib/alchemy/custom/model/el_finder/connector.rb, line 168
def _ls
  @response[:list] = []
end
_open(volume = nil, target = nil, payload: {}) click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 173
def _open(volume = nil, target = nil, payload: {})
  if @params[:init]
    _open_init
    return
  end

  volume ||= @volume
  target ||= @target

  if volume.nil?
    _open(@volumes[0], nil, payload: payload)
    return
  end

  if target.nil?
    _open(volume, '.', payload: payload)
    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] = volume.cwd(target)
    @response[:files] = volume.files(target)
    @response.merge!(payload)

    # @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
    @response[:options] = {}
    if @params[:init]
      @response = init_request(@response, volume: volume)
    else
      #se non siamo in init, allora inseriamo l'elenco dei comandi che il volume aperto non supporta
      @response[:options][:disabled] = init_request(@response.dup, volume: volume)[:options][:disabled]
    end

  else
    @response[:error] = "Directory does not exist"
    _open(@root) if File.directory?(@root)
  end

end
_open_init() click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 267
def _open_init
  @response[:cwd] = @volumes[0].cwd

  files = []
  @volumes.each {|v| files.concat(v.files)}
  @response[:files] = files
  @response = init_request(@response, volume: @volumes[0])
end
_paste() click to toggle source

of open_init

# File lib/alchemy/custom/model/el_finder/connector.rb, line 278
def _paste

  moved_files = []
  @targets.to_a.each do |src_v, src_f|

    #scopro il volume di destinazione
    dst_v, dst_f = from_hash(@params[:dst])

    if dst_v.is_a?(Volumes::ComponentAttribute)
      moved_files << dst_v.copy(src_f)
    else
      @response[:error] ||= 'Copia non consentita'
    end

  end
  @params[:tree] = true

  # dest_vlm = @targets.first[0]
  dest_vlm = from_hash(@params[:dst])[0]

  dest_target = dest_vlm.decode(dest_vlm.encode('.'))

  _open(dest_vlm, dest_target, payload: {moved_files: moved_files.collect {|v| dest_vlm.path_info(v)}})
end
_resize() click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 314
def _resize
  if @target.is_image?

    file = @target.file
    case @params[:mode]
    when 'resize'
      file = file.thumb("#{@params[:width]}x#{@params[:height]}!")
    when 'crop'
      file = file.thumb("#{@params[:width]}x#{@params[:height]}+#{@params[:x]}+#{@params[:y]}")
    when 'rotate'

      command = []
      command << "-background #{@params[:bg]}" unless @params[:bg].blank?
      command << "-rotate #{@params[:degree]}"

      file = file.convert(command.join(' '))
    else
      @response[:error] = "Mode:#{@params[:mode]} not implemented"
      return
    end
    file = file.convert("-quality #{@params[:quality]}") if @params[:quality].to_i < 100
    @target.file = file
    @target.save

    @response[:changed] = [to_hash(@target)]
    _open(@volume, @volume.root_path)
  else
    @response[:error] = "Unable to resize file. It does not exist"
  end
end
_rm() click to toggle source

of paste

# File lib/alchemy/custom/model/el_finder/connector.rb, line 306
def _rm
  @response[:removed] = @targets.to_a.collect do |src_v, src_f|
    src_v.rm(src_f)
    src_v.encode(src_f.path.to_s)
  end
end
_tree(volume = nil, target = nil) click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 242
def _tree(volume = nil, target = nil)
  volume ||= @volume
  target ||= @target

  @response[:api] = VERSION
  @response[:tree] = volume.tree(target)

end
_upload() click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 375
def _upload
  if @volume && @target
    response = @volume.upload(@target, @params[:upload])
    @response.merge!(response)
    # _open(@volume, @target)
  else
    @response[:error] = "errUploadCommon"
  end
  # 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
init_request(payload, volume:) click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 251
def init_request(payload, volume:)
  payload[:api] = VERSION
  # payload[:disabled] = @options[:disabled_commands]
  payload[:options] = {
      :dotFiles => @options[:allow_dot_files],
      :uplMaxSize => @options[:upload_max_size],
      :uploadMaxConn => -1, #configurazione per cui non deve spezzare in chucks i files
      :archives => [], #@options[:archivers].keys,
      :extract => [], #@options[:extractors].keys,
      :url => @options[:url],
      disabled: @options[:disabled_commands] + volume.disabled_commands
  }

  payload
end

Private Instance Methods

command_not_implemented() click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 431
def command_not_implemented
  @response[:error] = "Command '#{@params[:cmd]}' not yet implemented"
end
invalid_request() click to toggle source
# File lib/alchemy/custom/model/el_finder/connector.rb, line 424
def invalid_request
  @response[:error] = "Invalid command '#{@params[:cmd]}'"
end
mime_handler() click to toggle source

of upload

# File lib/alchemy/custom/model/el_finder/connector.rb, line 414
def mime_handler
  @options[:mime_handler]
end