module EL::Finder

Public Class Methods

included(base) click to toggle source
# File lib/el-finder/el-finder.rb, line 6
 def self.included base
  if EUtils.is_app?(base)

    base.class_exec do
      private
      # render a FileManager interface
      #
      # by default `el-finder` will use a textarea to edit files.
      #
      # to use Ace editor, install and load `el-ace` gem.
      # see https://github.com/espresso/el-ace for instructions
      # then simply set editor via `:editor` option:
      #
      # @example
      #   finder 'path/to/files', editor: :ace, some: :opts
      #
      # to use CKEditor editor, install and load `el-ckeditor` gem.
      # see https://github.com/espresso/el-ckeditor for instructions
      # then simply set editor via `:editor` option:
      #
      # @example
      #   finder 'path/to/files', editor: :ckeditor, some: :opts
      #
      def finder root, opts = {}
        (action = params[:action]) && (action = action.gsub(/\W/, '').to_sym)
        if action && self.class::ELFinderController[action]
          halt self.class::ELFinderController.new(action).call(env.merge(ROOT: root))
        end

        if editor = opts[:editor]
          editors = [:ace, :ckeditor]
          editors.include?(editor) ||
            raise(ArgumentError, 'Unknown editor "%s". Use one of :%s' % [escape_html(editor), editors*', :'])
        end

        fetch self.class::ELFinderController, :index, params do |env|
          env.update PARENT_ROUTE: route(action()), EDITOR_OPTS: opts, ROOT: root
        end
      end
    end

    base.mount_controller base.const_set(:ELFinderController, Class.new(E) {

      include EUtils
      include EL::FinderHelpers
      include EL::Ace if defined?(EL::Ace)
      include EL::CKE if defined?(EL::CKE)

      map '/el-finder-controller'
      engine :Slim
      view_prefix '/'
      view_fullpath File.expand_path('../templates', __FILE__).freeze
      layout false

      before do
        path = File.join(root, *params.values_at(:path, :name).compact)
        @entry = normalize_path(path).freeze
      end

      before /post_f/ do
        @current_entry = @entry
        @new_entry = File.join(@entry, normalize_path(params[:new_name]))
        File.directory?(@current_entry) || halt(400, '"%s" should be a directory' % escape_html(params[:name].to_s))
        File.exists?(@new_entry) && halt(400, '"%s" already exists' % escape_html(params[:new_name].to_s))
      end

      before /delete_f/ do
        if action_name == :file
          File.file?(@entry) || halt(400, '"%s" should be a file' % escape_html(params[:name].to_s))
        elsif action_name == :folder
          File.directory?(@entry) || halt(400, '"%s" should be a directory' % escape_html(params[:name].to_s))
        end
      end

      before :post_rename do
        @current_entry = @entry
        @new_entry = normalize_path(File.join(root, *params.values_at(:path, :new_name).compact))
        File.exists?(@current_entry) || halt(400, '"%s" does not exists' % escape_html(params[:name].to_s))
        File.exists?(@new_entry) && halt(400, '"%s" already  exists' % escape_html(params[:new_name].to_s))
      end

      def index
        render
      end

      def post_file
        FileUtils.touch(@new_entry)
      end
      
      def post_folder
        FileUtils.mkdir(@new_entry)
      end

      def post_rename
        FileUtils.mv(@current_entry, @new_entry)
      end

      def post_update
        File.open(@entry, 'w') {|f| f << params[:content]}
      end

      def delete_file
        File.unlink(@entry)
      end

      def delete_folder
        [root, @entry].map {|p| File.expand_path(normalize_path(p))}.uniq.size > 1 &&
          FileUtils.rm_rf(@entry)
      end

      def get_image
        env['PATH_INFO'] = normalize_path(params[:image].to_s)
        send_file File.join(root, env['PATH_INFO'])
      end

      def get_download
        attachment @entry
      end

      def post_upload
        File.directory?(@entry) || halt(400, '"%s" should be a directory' % escape_html(@entry))
        files = params[:files]  || halt(400, 'No files given')
        puts
        p env
        files.each do |f|
          FileUtils.mv f[:tempfile], File.join(@entry, f[:filename])
        end
      end

      def post_move
        source, target = params.values_at(:source, :target).map do |p|
          File.join(root, normalize_path(p))
        end
        FileUtils.mv source, target
      end

      def get_assets(*)
        env['PATH_INFO'] = env['PATH_INFO'].to_s.sub(self.class::ASSETS_REGEXP, '')
        send_files self.class::ASSETS_PATH
      end
    })

  else
    raise ArgumentError, '"%s" is not a Espresso controller' % base
  end
end

Public Instance Methods

delete_file() click to toggle source
# File lib/el-finder/el-finder.rb, line 107
def delete_file
  File.unlink(@entry)
end
delete_folder() click to toggle source
# File lib/el-finder/el-finder.rb, line 111
def delete_folder
  [root, @entry].map {|p| File.expand_path(normalize_path(p))}.uniq.size > 1 &&
    FileUtils.rm_rf(@entry)
end
finder(root, opts = {}) click to toggle source

render a FileManager interface

by default ‘el-finder` will use a textarea to edit files.

to use Ace editor, install and load ‘el-ace` gem. see github.com/espresso/el-ace for instructions then simply set editor via `:editor` option:

@example

finder 'path/to/files', editor: :ace, some: :opts

to use CKEditor editor, install and load ‘el-ckeditor` gem. see github.com/espresso/el-ckeditor for instructions then simply set editor via `:editor` option:

@example

finder 'path/to/files', editor: :ckeditor, some: :opts
# File lib/el-finder/el-finder.rb, line 29
def finder root, opts = {}
  (action = params[:action]) && (action = action.gsub(/\W/, '').to_sym)
  if action && self.class::ELFinderController[action]
    halt self.class::ELFinderController.new(action).call(env.merge(ROOT: root))
  end

  if editor = opts[:editor]
    editors = [:ace, :ckeditor]
    editors.include?(editor) ||
      raise(ArgumentError, 'Unknown editor "%s". Use one of :%s' % [escape_html(editor), editors*', :'])
  end

  fetch self.class::ELFinderController, :index, params do |env|
    env.update PARENT_ROUTE: route(action()), EDITOR_OPTS: opts, ROOT: root
  end
end
get_assets(*) click to toggle source
# File lib/el-finder/el-finder.rb, line 142
def get_assets(*)
  env['PATH_INFO'] = env['PATH_INFO'].to_s.sub(self.class::ASSETS_REGEXP, '')
  send_files self.class::ASSETS_PATH
end
get_download() click to toggle source
# File lib/el-finder/el-finder.rb, line 121
def get_download
  attachment @entry
end
get_image() click to toggle source
# File lib/el-finder/el-finder.rb, line 116
def get_image
  env['PATH_INFO'] = normalize_path(params[:image].to_s)
  send_file File.join(root, env['PATH_INFO'])
end
index() click to toggle source
# File lib/el-finder/el-finder.rb, line 87
def index
  render
end
post_file() click to toggle source
# File lib/el-finder/el-finder.rb, line 91
def post_file
  FileUtils.touch(@new_entry)
end
post_folder() click to toggle source
# File lib/el-finder/el-finder.rb, line 95
def post_folder
  FileUtils.mkdir(@new_entry)
end
post_move() click to toggle source
# File lib/el-finder/el-finder.rb, line 135
def post_move
  source, target = params.values_at(:source, :target).map do |p|
    File.join(root, normalize_path(p))
  end
  FileUtils.mv source, target
end
post_rename() click to toggle source
# File lib/el-finder/el-finder.rb, line 99
def post_rename
  FileUtils.mv(@current_entry, @new_entry)
end
post_update() click to toggle source
# File lib/el-finder/el-finder.rb, line 103
def post_update
  File.open(@entry, 'w') {|f| f << params[:content]}
end
post_upload() click to toggle source
# File lib/el-finder/el-finder.rb, line 125
def post_upload
  File.directory?(@entry) || halt(400, '"%s" should be a directory' % escape_html(@entry))
  files = params[:files]  || halt(400, 'No files given')
  puts
  p env
  files.each do |f|
    FileUtils.mv f[:tempfile], File.join(@entry, f[:filename])
  end
end