Skip to content

Instantly share code, notes, and snippets.

@eltiare
Created February 5, 2010 23:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eltiare/296355 to your computer and use it in GitHub Desktop.
Save eltiare/296355 to your computer and use it in GitHub Desktop.
# Routes
match '/javascripts/ckeditor/plugins/filemanager/connectors/rb/filemanager.rb', :to => 'filemanager#show'
match '/javascripts/ckeditor/plugins/filemanager/scripts/jquery.filetree/connectors/jqueryFileTree.rb', :to => 'filemanager#filetree'
# Duck punching
class Pathname
def /(other); File.join(self, other) end
end
class String
def /(other); File.join(self, other) end
end
# Controller
class FilemanagerController < ApplicationController
PUBLIC_PATH = '/images/user'
BASE_PATH = Rails.root / 'public'
PATH = BASE_PATH / PUBLIC_PATH
NOT_FOUND = 404
NOT_ACCEPTABLE = 406
def show
respond_to?(params[:mode]) ? send(params[:mode]) : action_not_found
end
def filetree
dir = clean_path(params[:dir])
raise StandardError.new("Invalid path: #{params[:dir]}") unless check_paths(dir)
Dir.chdir(BASE_PATH / dir)
listings = Dir.glob("*")
@dirs = listings.map { |l| "#{l}/" if File.directory?(l) }.compact
@files = listings.map { |l| l if File.file?(l) }.compact
render :layout => false
rescue => e
render :text => "There was an error: #{e}"
end
def add
dir = clean_path(params[:currentpath])
error("Invalid path: #{dir}") and return unless check_paths(dir)
error("Invalid image upload") and return unless params[:newfile].content_type.match(/^image/)
File.copy params[:newfile].path, BASE_PATH / dir / params[:newfile].original_path
success('File uploaded', :Path => dir, :Name => params[:newfile].original_path, :wrap_tag => 'textarea')
rescue => e
error(e)
end
def delete
path = clean_path(params[:path])
error("Invalid path: #{dir}") and return unless check_paths(path)
path = BASE_PATH / path
FileUtils.rm_rf(path)
success('', :Path => params[:path])
rescue => e
error(e)
end
def rename
old_path, new_path = clean_paths(params[:old], params[:new])
return unless check_paths(old_path)
old_full_path = BASE_PATH / old_path
new_full_path = File.dirname(old_full_path) / new_path
if File.exists?(old_full_path)
File.mv(old_full_path, new_full_path)
success('', {
'Old Path' => old_path,
'Old Name' => File.basename(old_path),
'New Path' => File.dirname(old_path) / new_path,
'New Name' => new_path
})
else
not_found(old_path)
end
rescue => e
error(e)
end
def addfolder
path, name = clean_paths(params[:path], params[:name])
return unless check_paths(path / name)
Dir.mkdir(BASE_PATH / path / name)
success("Folder created", :Parent => params[:path], :Name => params[:name])
rescue => e
error(e)
end
def getfolder
path = clean_path(params[:path])
return unless check_paths(path)
Dir.chdir(BASE_PATH / path)
return_val = {};
Dir.glob('*').each { |file|
return_val[ path / file] = {
:Path => path /file,
:Filename => file,
'File Type' => File.extname(file),
'Preview' => path / file,
'Properties' => {
'Date Created' => nil, #what's up with File not having creation date function?
'Date Modified' => File.mtime(file),
'Size' => File.size(file)
},
'Error' => '',
'Code' => 0
} unless File.directory?(file)
}
render_obj(return_val)
end
def getinfo
path = clean_path(params[:path])
return unless check_paths(path)
success('', {
:Path => path,
:Filename => File.basename(path),
'Properties' => {
'Date Created' => nil, #what's up with File not having creation date function?
'Date Modified' => File.mtime(BASE_PATH / path),
'Size' => File.size(BASE_PATH / path)
}
})
rescue => e
error(e)
end
private
def action_not_found
render_obj({'Error' => 'Action not found', :Code => NOT_FOUND})
end
def success(msg, opts)
render_obj(opts.merge('Error' => msg, :Code => 0))
end
def error(e)
render_obj('Error' => "The following error occurred: #{e}", :Code => 500)
end
def not_found(path)
render_obj({'Error' => "File not found: #{path.sub(BASE_PATH, '')}", :Code => NOT_FOUND})
end
def render_obj(obj, opts = {})
wrap_tag = obj.delete(:wrap_tag) || opts.delete(:wrap_tag)
text = if wrap_tag
"<#{wrap_tag}>#{obj.to_json}</#{wrap_tag}>"
else
obj.to_json
end
render opts.merge(:text => text, :layout => false)
end
def check_paths(*args)
args.each { |a|
unless %r"^#{PATH}"i.match(File.expand_path(BASE_PATH / a))
render_obj({
'Error' => "Invalid path: #{a}",
'Code' => NOT_ACCEPTABLE
})
return false
end
}
true
end
def clean_path(path)
path.gsub('../', './')
end
def clean_paths(*args)
args.map { |a| clean_path(a) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment